diff options
Diffstat (limited to '3rdparty/lzma/CPP/7zip')
327 files changed, 32382 insertions, 12057 deletions
diff --git a/3rdparty/lzma/CPP/7zip/7zip.mak b/3rdparty/lzma/CPP/7zip/7zip.mak index 7fbe2ada738..6f4a0a1c7fe 100644 --- a/3rdparty/lzma/CPP/7zip/7zip.mak +++ b/3rdparty/lzma/CPP/7zip/7zip.mak @@ -5,14 +5,14 @@ OBJS = \ $(WIN_OBJS) \ $(WIN_CTRL_OBJS) \ $(7ZIP_COMMON_OBJS) \ - $(AR_OBJS) \ - $(AR_COMMON_OBJS) \ $(UI_COMMON_OBJS) \ $(AGENT_OBJS) \ $(CONSOLE_OBJS) \ $(EXPLORER_OBJS) \ $(FM_OBJS) \ $(GUI_OBJS) \ + $(AR_COMMON_OBJS) \ + $(AR_OBJS) \ $(7Z_OBJS) \ $(CAB_OBJS) \ $(CHM_OBJS) \ diff --git a/3rdparty/lzma/CPP/7zip/7zip_gcc.mak b/3rdparty/lzma/CPP/7zip/7zip_gcc.mak new file mode 100644 index 00000000000..8bf0594ef6b --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/7zip_gcc.mak @@ -0,0 +1,1294 @@ +# USE_CLANG=1 +# USE_ASM = 1 +# IS_X64 = 1 +# MY_ARCH = +# USE_ASM= +# USE_JWASM=1 + +MY_ARCH_2 = $(MY_ARCH) + +MY_ASM = asmc +ifdef USE_JWASM +MY_ASM = jwasm +endif + +ifndef RC +RC=windres.exe --target=pe-x86-64 +RC=windres.exe -F pe-i386 +RC=windres.exe +endif + + +PROGPATH = $(O)/$(PROG) +PROGPATH_STATIC = $(O)/$(PROG)s + + +ifneq ($(CC), xlc) +CFLAGS_WARN_WALL = -Werror -Wall -Wextra +endif + +# for object file +# -Wa,-aln=test.s +# -save-temps +CFLAGS_BASE_LIST = -c +# CFLAGS_BASE_LIST = -S +CFLAGS_BASE = -O2 $(CFLAGS_BASE_LIST) $(CFLAGS_WARN_WALL) $(CFLAGS_WARN) \ + -DNDEBUG -D_REENTRANT -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ + -fPIC + +FLAGS_FLTO = -ffunction-sections +FLAGS_FLTO = -flto +FLAGS_FLTO = +# +# -DZ7_AFFINITY_DISABLE + + +ifdef SystemDrive +IS_MINGW = 1 +else +ifdef SYSTEMDRIVE +# ifdef OS +IS_MINGW = 1 +endif +endif + +ifdef IS_MINGW +LDFLAGS_STATIC_2 = -static +else +ifndef DEF_FILE +ifndef IS_NOT_STANDALONE +ifndef MY_DYNAMIC_LINK +ifneq ($(CC), clang) +LDFLAGS_STATIC_2 = +# -static +# -static-libstdc++ -static-libgcc +endif +endif +endif +endif +endif + +LDFLAGS_STATIC = -DNDEBUG $(LDFLAGS_STATIC_2) + +ifndef O + ifdef IS_MINGW + O=_o + else + O=_o + endif +endif + + +ifdef DEF_FILE + + +ifdef IS_MINGW +SHARED_EXT=.dll +LDFLAGS = -shared -DEF $(DEF_FILE) $(LDFLAGS_STATIC) +else +SHARED_EXT=.so +LDFLAGS = -shared -fPIC $(LDFLAGS_STATIC) +CC_SHARED=-fPIC +endif + + +else + +LDFLAGS = $(LDFLAGS_STATIC) +# -s is not required for clang, do we need it for GCC ??? + +#-static -static-libgcc -static-libstdc++ + +ifdef IS_MINGW +SHARED_EXT=.exe +else +SHARED_EXT= +endif + +endif + + +PROGPATH = $(O)/$(PROG)$(SHARED_EXT) +PROGPATH_STATIC = $(O)/$(PROG)s$(SHARED_EXT) + +ifdef IS_MINGW + +ifdef MSYSTEM +RM = rm -f +MY_MKDIR=mkdir -p +DEL_OBJ_EXE = -$(RM) $(PROGPATH) $(PROGPATH_STATIC) $(OBJS) +LIB_HTMLHELP=-lhtmlhelp +else +RM = del +MY_MKDIR=mkdir +DEL_OBJ_EXE = -$(RM) $(O)\*.o $(O)\$(PROG).exe $(O)\$(PROG).dll +endif + +LIB2_GUI = -lOle32 -lGdi32 -lComctl32 -lComdlg32 -lShell32 $(LIB_HTMLHELP) +LIB2 = -loleaut32 -luuid -ladvapi32 -lUser32 $(LIB2_GUI) + +CXXFLAGS_EXTRA = -DUNICODE -D_UNICODE +# -Wno-delete-non-virtual-dtor + + +else + +RM = rm -f +MY_MKDIR=mkdir -p +DEL_OBJ_EXE = -$(RM) $(PROGPATH) $(PROGPATH_STATIC) $(OBJS) + +# CFLAGS_BASE := $(CFLAGS_BASE) -DZ7_ST +# CXXFLAGS_EXTRA = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE + +# LOCAL_LIBS=-lpthread +# LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl +LIB2 = -lpthread -ldl + + +endif + + + +CFLAGS = $(MY_ARCH_2) $(LOCAL_FLAGS) $(CFLAGS_BASE2) $(CFLAGS_BASE) $(FLAGS_FLTO) $(CC_SHARED) -o $@ + + +ifdef IS_MINGW + +ifdef IS_X64 +AFLAGS_ABI = -win64 +else +AFLAGS_ABI = -coff -DABI_CDECL +# -DABI_CDECL +# -DABI_LINUX +# -DABI_CDECL +endif +AFLAGS = -nologo $(AFLAGS_ABI) -Fo$(O)/$(basename $(<F)).o + +else # IS_MINGW + +ifdef IS_X64 +AFLAGS_ABI = -elf64 -DABI_LINUX +else +AFLAGS_ABI = -elf -DABI_LINUX -DABI_CDECL +# -DABI_CDECL +# -DABI_LINUX +# -DABI_CDECL +endif +AFLAGS = -nologo $(AFLAGS_ABI) -Fo$(O)/ + +endif # IS_MINGW + + + +ifdef USE_ASM +CONSOLE_ASM_FLAGS=-DZ7_7ZIP_ASM +else +CONSOLE_ASM_FLAGS= +endif + +CXX_WARN_FLAGS = +#-Wno-invalid-offsetof +#-Wno-reorder + +CXXFLAGS = $(MY_ARCH_2) $(LOCAL_FLAGS) $(CXXFLAGS_BASE2) $(CFLAGS_BASE) $(FLAGS_FLTO) $(CXXFLAGS_EXTRA) $(CC_SHARED) $(CXX_WARN_FLAGS) $(CXX_STD_FLAGS) -o $@ + +STATIC_TARGET= +ifdef COMPL_STATIC +STATIC_TARGET=$(PROGPATH_STATIC) +endif + + +all: $(O) $(PROGPATH) $(STATIC_TARGET) + +$(O): + $(MY_MKDIR) $(O) + +# LDFLAGS3= -flto +# LDFLAGS3= -Wl,--gc-sections +# -Wl,--print-gc-sections + +ifneq ($(CC), $(CROSS_COMPILE)clang) +LFLAGS_STRIP = -s +endif + +LFLAGS_ALL = $(LFLAGS_STRIP) $(MY_ARCH_2) $(LDFLAGS) $(FLAGS_FLTO) $(LD_arch) $(OBJS) $(MY_LIBS) $(LIB2) + +# -s : GCC : Remove all symbol table and relocation information from the executable. +# -s : CLANG : unsupported +# -s + +$(PROGPATH): $(OBJS) + $(CXX) -o $(PROGPATH) $(LFLAGS_ALL) + +$(PROGPATH_STATIC): $(OBJS) + $(CXX) -static -o $(PROGPATH_STATIC) $(LFLAGS_ALL) + +# -s strips debug sections from executable in GCC + + + + +ifndef NO_DEFAULT_RES +$O/resource.o: resource.rc + $(RC) $(RFLAGS) resource.rc $@ + +# windres.exe : in old version mingw: +# $(RFLAGS) resource.rc $O/resource.o +# windres.exe : in new version mingw: +# $(RC) $(RFLAGS) resource.rc -FO $@ + + +endif + +$O/LzmaAlone.o: LzmaAlone.cpp + $(CXX) $(CXXFLAGS) $< + + +$O/CommandLineParser.o: ../../../Common/CommandLineParser.cpp + $(CXX) $(CXXFLAGS) $< +$O/CRC.o: ../../../Common/CRC.cpp + $(CXX) $(CXXFLAGS) $< + +$O/CrcReg.o: ../../../Common/CrcReg.cpp + $(CXX) $(CXXFLAGS) $< + +$O/DynLimBuf.o: ../../../Common/DynLimBuf.cpp + $(CXX) $(CXXFLAGS) $< +$O/IntToString.o: ../../../Common/IntToString.cpp + $(CXX) $(CXXFLAGS) $< +$O/Lang.o: ../../../Common/Lang.cpp + $(CXX) $(CXXFLAGS) $< +$O/ListFileUtils.o: ../../../Common/ListFileUtils.cpp + $(CXX) $(CXXFLAGS) $< +$O/LzFindPrepare.o: ../../../Common/LzFindPrepare.cpp + $(CXX) $(CXXFLAGS) $< +$O/MyMap.o: ../../../Common/MyMap.cpp + $(CXX) $(CXXFLAGS) $< +$O/MyString.o: ../../../Common/MyString.cpp + $(CXX) $(CXXFLAGS) $< +$O/MyVector.o: ../../../Common/MyVector.cpp + $(CXX) $(CXXFLAGS) $< +$O/MyWindows.o: ../../../Common/MyWindows.cpp + $(CXX) $(CXXFLAGS) $< +$O/MyWindows2.o: ../../../Common/MyWindows2.cpp + $(CXX) $(CXXFLAGS) $< +$O/MyXml.o: ../../../Common/MyXml.cpp + $(CXX) $(CXXFLAGS) $< +$O/NewHandler.o: ../../../Common/NewHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/Random.o: ../../../Common/Random.cpp + $(CXX) $(CXXFLAGS) $< +$O/Sha1Prepare.o: ../../../Common/Sha1Prepare.cpp + $(CXX) $(CXXFLAGS) $< +$O/Sha1Reg.o: ../../../Common/Sha1Reg.cpp + $(CXX) $(CXXFLAGS) $< +$O/Sha256Prepare.o: ../../../Common/Sha256Prepare.cpp + $(CXX) $(CXXFLAGS) $< +$O/Sha256Reg.o: ../../../Common/Sha256Reg.cpp + $(CXX) $(CXXFLAGS) $< +$O/StdInStream.o: ../../../Common/StdInStream.cpp + $(CXX) $(CXXFLAGS) $< +$O/StdOutStream.o: ../../../Common/StdOutStream.cpp + $(CXX) $(CXXFLAGS) $< +$O/StringConvert.o: ../../../Common/StringConvert.cpp + $(CXX) $(CXXFLAGS) $< +$O/StringToInt.o: ../../../Common/StringToInt.cpp + $(CXX) $(CXXFLAGS) $< +$O/TextConfig.o: ../../../Common/TextConfig.cpp + $(CXX) $(CXXFLAGS) $< +$O/UTFConvert.o: ../../../Common/UTFConvert.cpp + $(CXX) $(CXXFLAGS) $< +$O/Wildcard.o: ../../../Common/Wildcard.cpp + $(CXX) $(CXXFLAGS) $< +$O/XzCrc64Init.o: ../../../Common/XzCrc64Init.cpp + $(CXX) $(CXXFLAGS) $< +$O/XzCrc64Reg.o: ../../../Common/XzCrc64Reg.cpp + $(CXX) $(CXXFLAGS) $< + + + +$O/Clipboard.o: ../../../Windows/Clipboard.cpp + $(CXX) $(CXXFLAGS) $< +$O/COM.o: ../../../Windows/COM.cpp + $(CXX) $(CXXFLAGS) $< +$O/CommonDialog.o: ../../../Windows/CommonDialog.cpp + $(CXX) $(CXXFLAGS) $< +$O/Console.o: ../../../Windows/Console.cpp + $(CXX) $(CXXFLAGS) $< +$O/DLL.o: ../../../Windows/DLL.cpp + $(CXX) $(CXXFLAGS) $< +$O/ErrorMsg.o: ../../../Windows/ErrorMsg.cpp + $(CXX) $(CXXFLAGS) $< +$O/FileDir.o: ../../../Windows/FileDir.cpp + $(CXX) $(CXXFLAGS) $< +$O/FileFind.o: ../../../Windows/FileFind.cpp + $(CXX) $(CXXFLAGS) $< + +$O/FileIO.o: ../../../Windows/FileIO.cpp + $(CXX) $(CXXFLAGS) $< + +$O/FileLink.o: ../../../Windows/FileLink.cpp + $(CXX) $(CXXFLAGS) $< +$O/FileMapping.o: ../../../Windows/FileMapping.cpp + $(CXX) $(CXXFLAGS) $< +$O/FileName.o: ../../../Windows/FileName.cpp + $(CXX) $(CXXFLAGS) $< +$O/FileSystem.o: ../../../Windows/FileSystem.cpp + $(CXX) $(CXXFLAGS) $< +$O/MemoryGlobal.o: ../../../Windows/MemoryGlobal.cpp + $(CXX) $(CXXFLAGS) $< +$O/MemoryLock.o: ../../../Windows/MemoryLock.cpp + $(CXX) $(CXXFLAGS) $< +$O/Menu.o: ../../../Windows/Menu.cpp + $(CXX) $(CXXFLAGS) $< +$O/NationalTime.o: ../../../Windows/NationalTime.cpp + $(CXX) $(CXXFLAGS) $< +$O/Net.o: ../../../Windows/Net.cpp + $(CXX) $(CXXFLAGS) $< +$O/ProcessMessages.o: ../../../Windows/ProcessMessages.cpp + $(CXX) $(CXXFLAGS) $< +$O/ProcessUtils.o: ../../../Windows/ProcessUtils.cpp + $(CXX) $(CXXFLAGS) $< +$O/PropVariant.o: ../../../Windows/PropVariant.cpp + $(CXX) $(CXXFLAGS) $< +$O/PropVariantConv.o: ../../../Windows/PropVariantConv.cpp + $(CXX) $(CXXFLAGS) $< +$O/PropVariantUtils.o: ../../../Windows/PropVariantUtils.cpp + $(CXX) $(CXXFLAGS) $< +$O/Registry.o: ../../../Windows/Registry.cpp + $(CXX) $(CXXFLAGS) $< +$O/ResourceString.o: ../../../Windows/ResourceString.cpp + $(CXX) $(CXXFLAGS) $< +$O/SecurityUtils.o: ../../../Windows/SecurityUtils.cpp + $(CXX) $(CXXFLAGS) $< +$O/Shell.o: ../../../Windows/Shell.cpp + $(CXX) $(CXXFLAGS) $< +$O/Synchronization.o: ../../../Windows/Synchronization.cpp + $(CXX) $(CXXFLAGS) $< +$O/System.o: ../../../Windows/System.cpp + $(CXX) $(CXXFLAGS) $< +$O/SystemInfo.o: ../../../Windows/SystemInfo.cpp + $(CXX) $(CXXFLAGS) $< +$O/TimeUtils.o: ../../../Windows/TimeUtils.cpp + $(CXX) $(CXXFLAGS) $< +$O/Window.o: ../../../Windows/Window.cpp + $(CXX) $(CXXFLAGS) $< + + + +$O/ComboBox.o: ../../../Windows/Control/ComboBox.cpp + $(CXX) $(CXXFLAGS) $< +$O/Dialog.o: ../../../Windows/Control/Dialog.cpp + $(CXX) $(CXXFLAGS) $< +$O/ImageList.o: ../../../Windows/Control/ImageList.cpp + $(CXX) $(CXXFLAGS) $< +$O/ListView.o: ../../../Windows/Control/ListView.cpp + $(CXX) $(CXXFLAGS) $< +$O/PropertyPage.o: ../../../Windows/Control/PropertyPage.cpp + $(CXX) $(CXXFLAGS) $< +$O/Window2.o: ../../../Windows/Control/Window2.cpp + $(CXX) $(CXXFLAGS) $< + + +$O/CreateCoder.o: ../../Common/CreateCoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/CWrappers.o: ../../Common/CWrappers.cpp + $(CXX) $(CXXFLAGS) $< +$O/FilePathAutoRename.o: ../../Common/FilePathAutoRename.cpp + $(CXX) $(CXXFLAGS) $< +$O/FileStreams.o: ../../Common/FileStreams.cpp + $(CXX) $(CXXFLAGS) $< +$O/FilterCoder.o: ../../Common/FilterCoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/InBuffer.o: ../../Common/InBuffer.cpp + $(CXX) $(CXXFLAGS) $< +$O/InOutTempBuffer.o: ../../Common/InOutTempBuffer.cpp + $(CXX) $(CXXFLAGS) $< +$O/LimitedStreams.o: ../../Common/LimitedStreams.cpp + $(CXX) $(CXXFLAGS) $< +$O/LockedStream.o: ../../Common/LockedStream.cpp + $(CXX) $(CXXFLAGS) $< +$O/MemBlocks.o: ../../Common/MemBlocks.cpp + $(CXX) $(CXXFLAGS) $< +$O/MethodId.o: ../../Common/MethodId.cpp + $(CXX) $(CXXFLAGS) $< +$O/MethodProps.o: ../../Common/MethodProps.cpp + $(CXX) $(CXXFLAGS) $< +$O/MultiOutStream.o: ../../Common/MultiOutStream.cpp + $(CXX) $(CXXFLAGS) $< +$O/OffsetStream.o: ../../Common/OffsetStream.cpp + $(CXX) $(CXXFLAGS) $< +$O/OutBuffer.o: ../../Common/OutBuffer.cpp + $(CXX) $(CXXFLAGS) $< +$O/OutMemStream.o: ../../Common/OutMemStream.cpp + $(CXX) $(CXXFLAGS) $< +$O/ProgressMt.o: ../../Common/ProgressMt.cpp + $(CXX) $(CXXFLAGS) $< +$O/ProgressUtils.o: ../../Common/ProgressUtils.cpp + $(CXX) $(CXXFLAGS) $< +$O/PropId.o: ../../Common/PropId.cpp + $(CXX) $(CXXFLAGS) $< +$O/StreamBinder.o: ../../Common/StreamBinder.cpp + $(CXX) $(CXXFLAGS) $< +$O/StreamObjects.o: ../../Common/StreamObjects.cpp + $(CXX) $(CXXFLAGS) $< +$O/StreamUtils.o: ../../Common/StreamUtils.cpp + $(CXX) $(CXXFLAGS) $< +$O/UniqBlocks.o: ../../Common/UniqBlocks.cpp + $(CXX) $(CXXFLAGS) $< +$O/VirtThread.o: ../../Common/VirtThread.cpp + $(CXX) $(CXXFLAGS) $< + + +$O/ApfsHandler.o: ../../Archive/ApfsHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/ApmHandler.o: ../../Archive/ApmHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/ArchiveExports.o: ../../Archive/ArchiveExports.cpp + $(CXX) $(CXXFLAGS) $< +$O/ArHandler.o: ../../Archive/ArHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/ArjHandler.o: ../../Archive/ArjHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/AvbHandler.o: ../../Archive/AvbHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/Base64Handler.o: ../../Archive/Base64Handler.cpp + $(CXX) $(CXXFLAGS) $< +$O/Bz2Handler.o: ../../Archive/Bz2Handler.cpp + $(CXX) $(CXXFLAGS) $< +$O/ComHandler.o: ../../Archive/ComHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/CpioHandler.o: ../../Archive/CpioHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/CramfsHandler.o: ../../Archive/CramfsHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/DeflateProps.o: ../../Archive/DeflateProps.cpp + $(CXX) $(CXXFLAGS) $< +$O/DllExports.o: ../../Archive/DllExports.cpp + $(CXX) $(CXXFLAGS) $< +$O/DllExports2.o: ../../Archive/DllExports2.cpp + $(CXX) $(CXXFLAGS) $< +$O/DmgHandler.o: ../../Archive/DmgHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/ElfHandler.o: ../../Archive/ElfHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/ExtHandler.o: ../../Archive/ExtHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/FatHandler.o: ../../Archive/FatHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/FlvHandler.o: ../../Archive/FlvHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/GptHandler.o: ../../Archive/GptHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/GzHandler.o: ../../Archive/GzHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/HandlerCont.o: ../../Archive/HandlerCont.cpp + $(CXX) $(CXXFLAGS) $< +$O/HfsHandler.o: ../../Archive/HfsHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/IhexHandler.o: ../../Archive/IhexHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/LpHandler.o: ../../Archive/LpHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/LzhHandler.o: ../../Archive/LzhHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/LzmaHandler.o: ../../Archive/LzmaHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/MachoHandler.o: ../../Archive/MachoHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/MbrHandler.o: ../../Archive/MbrHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/MslzHandler.o: ../../Archive/MslzHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/MubHandler.o: ../../Archive/MubHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/NtfsHandler.o: ../../Archive/NtfsHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/PeHandler.o: ../../Archive/PeHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/PpmdHandler.o: ../../Archive/PpmdHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/QcowHandler.o: ../../Archive/QcowHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/RpmHandler.o: ../../Archive/RpmHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/SparseHandler.o: ../../Archive/SparseHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/SplitHandler.o: ../../Archive/SplitHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/SquashfsHandler.o: ../../Archive/SquashfsHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/SwfHandler.o: ../../Archive/SwfHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/UefiHandler.o: ../../Archive/UefiHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/VdiHandler.o: ../../Archive/VdiHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/VhdHandler.o: ../../Archive/VhdHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/VhdxHandler.o: ../../Archive/VhdxHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/VmdkHandler.o: ../../Archive/VmdkHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/XarHandler.o: ../../Archive/XarHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/XzHandler.o: ../../Archive/XzHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/ZHandler.o: ../../Archive/ZHandler.cpp + $(CXX) $(CXXFLAGS) $< + + +$O/7zCompressionMode.o: ../../Archive/7z/7zCompressionMode.cpp + $(CXX) $(CXXFLAGS) $< +$O/7zDecode.o: ../../Archive/7z/7zDecode.cpp + $(CXX) $(CXXFLAGS) $< +$O/7zEncode.o: ../../Archive/7z/7zEncode.cpp + $(CXX) $(CXXFLAGS) $< +$O/7zExtract.o: ../../Archive/7z/7zExtract.cpp + $(CXX) $(CXXFLAGS) $< +$O/7zFolderInStream.o: ../../Archive/7z/7zFolderInStream.cpp + $(CXX) $(CXXFLAGS) $< +$O/7zHandler.o: ../../Archive/7z/7zHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/7zHandlerOut.o: ../../Archive/7z/7zHandlerOut.cpp + $(CXX) $(CXXFLAGS) $< +$O/7zHeader.o: ../../Archive/7z/7zHeader.cpp + $(CXX) $(CXXFLAGS) $< +$O/7zIn.o: ../../Archive/7z/7zIn.cpp + $(CXX) $(CXXFLAGS) $< +$O/7zOut.o: ../../Archive/7z/7zOut.cpp + $(CXX) $(CXXFLAGS) $< +$O/7zProperties.o: ../../Archive/7z/7zProperties.cpp + $(CXX) $(CXXFLAGS) $< +$O/7zRegister.o: ../../Archive/7z/7zRegister.cpp + $(CXX) $(CXXFLAGS) $< +$O/7zSpecStream.o: ../../Archive/7z/7zSpecStream.cpp + $(CXX) $(CXXFLAGS) $< +$O/7zUpdate.o: ../../Archive/7z/7zUpdate.cpp + $(CXX) $(CXXFLAGS) $< + + +$O/CabBlockInStream.o: ../../Archive/Cab/CabBlockInStream.cpp + $(CXX) $(CXXFLAGS) $< +$O/CabHandler.o: ../../Archive/Cab/CabHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/CabHeader.o: ../../Archive/Cab/CabHeader.cpp + $(CXX) $(CXXFLAGS) $< +$O/CabIn.o: ../../Archive/Cab/CabIn.cpp + $(CXX) $(CXXFLAGS) $< +$O/CabRegister.o: ../../Archive/Cab/CabRegister.cpp + $(CXX) $(CXXFLAGS) $< + + +$O/ChmHandler.o: ../../Archive/Chm/ChmHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/ChmIn.o: ../../Archive/Chm/ChmIn.cpp + $(CXX) $(CXXFLAGS) $< + +$O/IsoHandler.o: ../../Archive/Iso/IsoHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/IsoHeader.o: ../../Archive/Iso/IsoHeader.cpp + $(CXX) $(CXXFLAGS) $< +$O/IsoIn.o: ../../Archive/Iso/IsoIn.cpp + $(CXX) $(CXXFLAGS) $< +$O/IsoRegister.o: ../../Archive/Iso/IsoRegister.cpp + $(CXX) $(CXXFLAGS) $< + +$O/NsisDecode.o: ../../Archive/Nsis/NsisDecode.cpp + $(CXX) $(CXXFLAGS) $< +$O/NsisHandler.o: ../../Archive/Nsis/NsisHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/NsisIn.o: ../../Archive/Nsis/NsisIn.cpp + $(CXX) $(CXXFLAGS) $< +$O/NsisRegister.o: ../../Archive/Nsis/NsisRegister.cpp + $(CXX) $(CXXFLAGS) $< + +$O/Rar5Handler.o: ../../Archive/Rar/Rar5Handler.cpp + $(CXX) $(CXXFLAGS) $< +$O/RarHandler.o: ../../Archive/Rar/RarHandler.cpp + $(CXX) $(CXXFLAGS) $< + +$O/TarHandler.o: ../../Archive/Tar/TarHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/TarHandlerOut.o: ../../Archive/Tar/TarHandlerOut.cpp + $(CXX) $(CXXFLAGS) $< +$O/TarHeader.o: ../../Archive/Tar/TarHeader.cpp + $(CXX) $(CXXFLAGS) $< +$O/TarIn.o: ../../Archive/Tar/TarIn.cpp + $(CXX) $(CXXFLAGS) $< +$O/TarOut.o: ../../Archive/Tar/TarOut.cpp + $(CXX) $(CXXFLAGS) $< +$O/TarRegister.o: ../../Archive/Tar/TarRegister.cpp + $(CXX) $(CXXFLAGS) $< +$O/TarUpdate.o: ../../Archive/Tar/TarUpdate.cpp + $(CXX) $(CXXFLAGS) $< + +$O/UdfHandler.o: ../../Archive/Udf/UdfHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/UdfIn.o: ../../Archive/Udf/UdfIn.cpp + $(CXX) $(CXXFLAGS) $< + + +$O/WimHandler.o: ../../Archive/Wim/WimHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/WimHandlerOut.o: ../../Archive/Wim/WimHandlerOut.cpp + $(CXX) $(CXXFLAGS) $< +$O/WimIn.o: ../../Archive/Wim/WimIn.cpp + $(CXX) $(CXXFLAGS) $< +$O/WimRegister.o: ../../Archive/Wim/WimRegister.cpp + $(CXX) $(CXXFLAGS) $< + + +$O/ZipAddCommon.o: ../../Archive/Zip/ZipAddCommon.cpp + $(CXX) $(CXXFLAGS) $< +$O/ZipHandler.o: ../../Archive/Zip/ZipHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/ZipHandlerOut.o: ../../Archive/Zip/ZipHandlerOut.cpp + $(CXX) $(CXXFLAGS) $< +$O/ZipIn.o: ../../Archive/Zip/ZipIn.cpp + $(CXX) $(CXXFLAGS) $< +$O/ZipItem.o: ../../Archive/Zip/ZipItem.cpp + $(CXX) $(CXXFLAGS) $< +$O/ZipOut.o: ../../Archive/Zip/ZipOut.cpp + $(CXX) $(CXXFLAGS) $< +$O/ZipUpdate.o: ../../Archive/Zip/ZipUpdate.cpp + $(CXX) $(CXXFLAGS) $< +$O/ZipRegister.o: ../../Archive/Zip/ZipRegister.cpp + $(CXX) $(CXXFLAGS) $< + + +$O/Bcj2Coder.o: ../../Compress/Bcj2Coder.cpp + $(CXX) $(CXXFLAGS) $< +$O/Bcj2Register.o: ../../Compress/Bcj2Register.cpp + $(CXX) $(CXXFLAGS) $< +$O/BcjCoder.o: ../../Compress/BcjCoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/BcjRegister.o: ../../Compress/BcjRegister.cpp + $(CXX) $(CXXFLAGS) $< +$O/BitlDecoder.o: ../../Compress/BitlDecoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/BranchMisc.o: ../../Compress/BranchMisc.cpp + $(CXX) $(CXXFLAGS) $< +$O/BranchRegister.o: ../../Compress/BranchRegister.cpp + $(CXX) $(CXXFLAGS) $< +$O/ByteSwap.o: ../../Compress/ByteSwap.cpp + $(CXX) $(CXXFLAGS) $< +$O/BZip2Crc.o: ../../Compress/BZip2Crc.cpp + $(CXX) $(CXXFLAGS) $< +$O/BZip2Decoder.o: ../../Compress/BZip2Decoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/BZip2Encoder.o: ../../Compress/BZip2Encoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/BZip2Register.o: ../../Compress/BZip2Register.cpp + $(CXX) $(CXXFLAGS) $< +$O/CodecExports.o: ../../Compress/CodecExports.cpp + $(CXX) $(CXXFLAGS) $< +$O/CopyCoder.o: ../../Compress/CopyCoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/CopyRegister.o: ../../Compress/CopyRegister.cpp + $(CXX) $(CXXFLAGS) $< +$O/Deflate64Register.o: ../../Compress/Deflate64Register.cpp + $(CXX) $(CXXFLAGS) $< +$O/DeflateDecoder.o: ../../Compress/DeflateDecoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/DeflateEncoder.o: ../../Compress/DeflateEncoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/DeflateRegister.o: ../../Compress/DeflateRegister.cpp + $(CXX) $(CXXFLAGS) $< +$O/DeltaFilter.o: ../../Compress/DeltaFilter.cpp + $(CXX) $(CXXFLAGS) $< +$O/DllExports2Compress.o: ../../Compress/DllExports2Compress.cpp + $(CXX) $(CXXFLAGS) $< +$O/DllExportsCompress.o: ../../Compress/DllExportsCompress.cpp + $(CXX) $(CXXFLAGS) $< +$O/ImplodeDecoder.o: ../../Compress/ImplodeDecoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/ImplodeHuffmanDecoder.o: ../../Compress/ImplodeHuffmanDecoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/LzfseDecoder.o: ../../Compress/LzfseDecoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/LzhDecoder.o: ../../Compress/LzhDecoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/Lzma2Decoder.o: ../../Compress/Lzma2Decoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/Lzma2Encoder.o: ../../Compress/Lzma2Encoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/Lzma2Register.o: ../../Compress/Lzma2Register.cpp + $(CXX) $(CXXFLAGS) $< +$O/LzmaDecoder.o: ../../Compress/LzmaDecoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/LzmaEncoder.o: ../../Compress/LzmaEncoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/LzmaRegister.o: ../../Compress/LzmaRegister.cpp + $(CXX) $(CXXFLAGS) $< +$O/LzmsDecoder.o: ../../Compress/LzmsDecoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/LzOutWindow.o: ../../Compress/LzOutWindow.cpp + $(CXX) $(CXXFLAGS) $< +$O/LzxDecoder.o: ../../Compress/LzxDecoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/PpmdDecoder.o: ../../Compress/PpmdDecoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/PpmdEncoder.o: ../../Compress/PpmdEncoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/PpmdRegister.o: ../../Compress/PpmdRegister.cpp + $(CXX) $(CXXFLAGS) $< +$O/PpmdZip.o: ../../Compress/PpmdZip.cpp + $(CXX) $(CXXFLAGS) $< +$O/QuantumDecoder.o: ../../Compress/QuantumDecoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/Rar1Decoder.o: ../../Compress/Rar1Decoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/Rar2Decoder.o: ../../Compress/Rar2Decoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/Rar3Decoder.o: ../../Compress/Rar3Decoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/Rar3Vm.o: ../../Compress/Rar3Vm.cpp + $(CXX) $(CXXFLAGS) $< +$O/Rar5Decoder.o: ../../Compress/Rar5Decoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/RarCodecsRegister.o: ../../Compress/RarCodecsRegister.cpp + $(CXX) $(CXXFLAGS) $< +$O/ShrinkDecoder.o: ../../Compress/ShrinkDecoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/XpressDecoder.o: ../../Compress/XpressDecoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/XzDecoder.o: ../../Compress/XzDecoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/XzEncoder.o: ../../Compress/XzEncoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/ZDecoder.o: ../../Compress/ZDecoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/ZlibDecoder.o: ../../Compress/ZlibDecoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/ZlibEncoder.o: ../../Compress/ZlibEncoder.cpp + $(CXX) $(CXXFLAGS) $< + + +$O/7zAes.o: ../../Crypto/7zAes.cpp + $(CXX) $(CXXFLAGS) $< +$O/7zAesRegister.o: ../../Crypto/7zAesRegister.cpp + $(CXX) $(CXXFLAGS) $< +$O/HmacSha1.o: ../../Crypto/HmacSha1.cpp + $(CXX) $(CXXFLAGS) $< +$O/HmacSha256.o: ../../Crypto/HmacSha256.cpp + $(CXX) $(CXXFLAGS) $< +$O/MyAes.o: ../../Crypto/MyAes.cpp + $(CXX) $(CXXFLAGS) $< +$O/MyAesReg.o: ../../Crypto/MyAesReg.cpp + $(CXX) $(CXXFLAGS) $< +$O/Pbkdf2HmacSha1.o: ../../Crypto/Pbkdf2HmacSha1.cpp + $(CXX) $(CXXFLAGS) $< +$O/RandGen.o: ../../Crypto/RandGen.cpp + $(CXX) $(CXXFLAGS) $< +$O/Rar20Crypto.o: ../../Crypto/Rar20Crypto.cpp + $(CXX) $(CXXFLAGS) $< +$O/Rar5Aes.o: ../../Crypto/Rar5Aes.cpp + $(CXX) $(CXXFLAGS) $< +$O/RarAes.o: ../../Crypto/RarAes.cpp + $(CXX) $(CXXFLAGS) $< +$O/WzAes.o: ../../Crypto/WzAes.cpp + $(CXX) $(CXXFLAGS) $< +$O/ZipCrypto.o: ../../Crypto/ZipCrypto.cpp + $(CXX) $(CXXFLAGS) $< +$O/ZipStrong.o: ../../Crypto/ZipStrong.cpp + $(CXX) $(CXXFLAGS) $< + + + +$O/CoderMixer2.o: ../../Archive/Common/CoderMixer2.cpp + $(CXX) $(CXXFLAGS) $< +$O/DummyOutStream.o: ../../Archive/Common/DummyOutStream.cpp + $(CXX) $(CXXFLAGS) $< +$O/FindSignature.o: ../../Archive/Common/FindSignature.cpp + $(CXX) $(CXXFLAGS) $< +$O/HandlerOut.o: ../../Archive/Common/HandlerOut.cpp + $(CXX) $(CXXFLAGS) $< +$O/InStreamWithCRC.o: ../../Archive/Common/InStreamWithCRC.cpp + $(CXX) $(CXXFLAGS) $< +$O/ItemNameUtils.o: ../../Archive/Common/ItemNameUtils.cpp + $(CXX) $(CXXFLAGS) $< +$O/MultiStream.o: ../../Archive/Common/MultiStream.cpp + $(CXX) $(CXXFLAGS) $< +$O/OutStreamWithCRC.o: ../../Archive/Common/OutStreamWithCRC.cpp + $(CXX) $(CXXFLAGS) $< +$O/OutStreamWithSha1.o: ../../Archive/Common/OutStreamWithSha1.cpp + $(CXX) $(CXXFLAGS) $< +$O/ParseProperties.o: ../../Archive/Common/ParseProperties.cpp + $(CXX) $(CXXFLAGS) $< + + + + +$O/ArchiveCommandLine.o: ../../UI/Common/ArchiveCommandLine.cpp + $(CXX) $(CXXFLAGS) $< +$O/ArchiveExtractCallback.o: ../../UI/Common/ArchiveExtractCallback.cpp + $(CXX) $(CXXFLAGS) $< +$O/ArchiveName.o: ../../UI/Common/ArchiveName.cpp + $(CXX) $(CXXFLAGS) $< +$O/ArchiveOpenCallback.o: ../../UI/Common/ArchiveOpenCallback.cpp + $(CXX) $(CXXFLAGS) $< +$O/Bench.o: ../../UI/Common/Bench.cpp + $(CXX) $(CXXFLAGS) $< +$O/CompressCall.o: ../../UI/Common/CompressCall.cpp + $(CXX) $(CXXFLAGS) $< +$O/CompressCall2.o: ../../UI/Common/CompressCall2.cpp + $(CXX) $(CXXFLAGS) $< +$O/DefaultName.o: ../../UI/Common/DefaultName.cpp + $(CXX) $(CXXFLAGS) $< +$O/EnumDirItems.o: ../../UI/Common/EnumDirItems.cpp + $(CXX) $(CXXFLAGS) $< +$O/Extract.o: ../../UI/Common/Extract.cpp + $(CXX) $(CXXFLAGS) $< +$O/ExtractingFilePath.o: ../../UI/Common/ExtractingFilePath.cpp + $(CXX) $(CXXFLAGS) $< +$O/HashCalc.o: ../../UI/Common/HashCalc.cpp + $(CXX) $(CXXFLAGS) $< +$O/LoadCodecs.o: ../../UI/Common/LoadCodecs.cpp + $(CXX) $(CXXFLAGS) $< +$O/OpenArchive.o: ../../UI/Common/OpenArchive.cpp + $(CXX) $(CXXFLAGS) $< +$O/PropIDUtils.o: ../../UI/Common/PropIDUtils.cpp + $(CXX) $(CXXFLAGS) $< +$O/SetProperties.o: ../../UI/Common/SetProperties.cpp + $(CXX) $(CXXFLAGS) $< +$O/SortUtils.o: ../../UI/Common/SortUtils.cpp + $(CXX) $(CXXFLAGS) $< +$O/TempFiles.o: ../../UI/Common/TempFiles.cpp + $(CXX) $(CXXFLAGS) $< +$O/Update.o: ../../UI/Common/Update.cpp + $(CXX) $(CXXFLAGS) $< +$O/UpdateAction.o: ../../UI/Common/UpdateAction.cpp + $(CXX) $(CXXFLAGS) $< +$O/UpdateCallback.o: ../../UI/Common/UpdateCallback.cpp + $(CXX) $(CXXFLAGS) $< +$O/UpdatePair.o: ../../UI/Common/UpdatePair.cpp + $(CXX) $(CXXFLAGS) $< +$O/UpdateProduce.o: ../../UI/Common/UpdateProduce.cpp + $(CXX) $(CXXFLAGS) $< +$O/WorkDir.o: ../../UI/Common/WorkDir.cpp + $(CXX) $(CXXFLAGS) $< +$O/ZipRegistry.o: ../../UI/Common/ZipRegistry.cpp + $(CXX) $(CXXFLAGS) $< + + +$O/Agent.o: ../../UI/Agent/Agent.cpp + $(CXX) $(CXXFLAGS) $< +$O/AgentOut.o: ../../UI/Agent/AgentOut.cpp + $(CXX) $(CXXFLAGS) $< +$O/AgentProxy.o: ../../UI/Agent/AgentProxy.cpp + $(CXX) $(CXXFLAGS) $< +$O/ArchiveFolder.o: ../../UI/Agent/ArchiveFolder.cpp + $(CXX) $(CXXFLAGS) $< +$O/ArchiveFolderOpen.o: ../../UI/Agent/ArchiveFolderOpen.cpp + $(CXX) $(CXXFLAGS) $< +$O/ArchiveFolderOut.o: ../../UI/Agent/ArchiveFolderOut.cpp + $(CXX) $(CXXFLAGS) $< +$O/UpdateCallbackAgent.o: ../../UI/Agent/UpdateCallbackAgent.cpp + $(CXX) $(CXXFLAGS) $< + + +$O/Client7z.o: ../../UI/Client7z/Client7z.cpp + $(CXX) $(CXXFLAGS) $< + + +$O/BenchCon.o: ../../UI/Console/BenchCon.cpp + $(CXX) $(CXXFLAGS) $< +$O/ConsoleClose.o: ../../UI/Console/ConsoleClose.cpp + $(CXX) $(CXXFLAGS) $< +$O/ExtractCallbackConsole.o: ../../UI/Console/ExtractCallbackConsole.cpp + $(CXX) $(CXXFLAGS) $< +$O/HashCon.o: ../../UI/Console/HashCon.cpp + $(CXX) $(CXXFLAGS) $< +$O/List.o: ../../UI/Console/List.cpp + $(CXX) $(CXXFLAGS) $< +$O/Main.o: ../../UI/Console/Main.cpp ../../../../C/7zVersion.h + $(CXX) $(CXXFLAGS) $(CONSOLE_VARIANT_FLAGS) $(CONSOLE_ASM_FLAGS) $< +$O/MainAr.o: ../../UI/Console/MainAr.cpp + $(CXX) $(CXXFLAGS) $< +$O/OpenCallbackConsole.o: ../../UI/Console/OpenCallbackConsole.cpp + $(CXX) $(CXXFLAGS) $< +$O/PercentPrinter.o: ../../UI/Console/PercentPrinter.cpp + $(CXX) $(CXXFLAGS) $< +$O/UpdateCallbackConsole.o: ../../UI/Console/UpdateCallbackConsole.cpp + $(CXX) $(CXXFLAGS) $< +$O/UserInputUtils.o: ../../UI/Console/UserInputUtils.cpp + $(CXX) $(CXXFLAGS) $< + +$O/BenchmarkDialog.o: ../../UI/GUI/BenchmarkDialog.cpp + $(CXX) $(CXXFLAGS) $< +$O/CompressDialog.o: ../../UI/GUI/CompressDialog.cpp + $(CXX) $(CXXFLAGS) $< +$O/ExtractDialog.o: ../../UI/GUI/ExtractDialog.cpp + $(CXX) $(CXXFLAGS) $< +$O/ExtractGUI.o: ../../UI/GUI/ExtractGUI.cpp + $(CXX) $(CXXFLAGS) $< +$O/GUI.o: ../../UI/GUI/GUI.cpp + $(CXX) $(CXXFLAGS) $< +$O/HashGUI.o: ../../UI/GUI/HashGUI.cpp + $(CXX) $(CXXFLAGS) $< +$O/UpdateCallbackGUI.o: ../../UI/GUI/UpdateCallbackGUI.cpp + $(CXX) $(CXXFLAGS) $< +$O/UpdateCallbackGUI2.o: ../../UI/GUI/UpdateCallbackGUI2.cpp + $(CXX) $(CXXFLAGS) $< +$O/UpdateGUI.o: ../../UI/GUI/UpdateGUI.cpp + $(CXX) $(CXXFLAGS) $< + +$O/MyMessages.o: ../../UI/Explorer/MyMessages.cpp + $(CXX) $(CXXFLAGS) $< +$O/ContextMenu.o: ../../UI/Explorer/ContextMenu.cpp + $(CXX) $(CXXFLAGS) $< +$O/DllExportsExplorer.o: ../../UI/Explorer/DllExportsExplorer.cpp + $(CXX) $(CXXFLAGS) $< +$O/RegistryContextMenu.o: ../../UI/Explorer/RegistryContextMenu.cpp + $(CXX) $(CXXFLAGS) $< + + + +$O/AboutDialog.o: ../../UI/FileManager/AboutDialog.cpp + $(CXX) $(CXXFLAGS) $< +$O/AltStreamsFolder.o: ../../UI/FileManager/AltStreamsFolder.cpp + $(CXX) $(CXXFLAGS) $< +$O/App.o: ../../UI/FileManager/App.cpp + $(CXX) $(CXXFLAGS) $< +$O/BrowseDialog.o: ../../UI/FileManager/BrowseDialog.cpp + $(CXX) $(CXXFLAGS) $< +$O/ClassDefs.o: ../../UI/FileManager/ClassDefs.cpp + $(CXX) $(CXXFLAGS) $< +$O/ComboDialog.o: ../../UI/FileManager/ComboDialog.cpp + $(CXX) $(CXXFLAGS) $< +$O/CopyDialog.o: ../../UI/FileManager/CopyDialog.cpp + $(CXX) $(CXXFLAGS) $< +$O/EditDialog.o: ../../UI/FileManager/EditDialog.cpp + $(CXX) $(CXXFLAGS) $< +$O/EditPage.o: ../../UI/FileManager/EditPage.cpp + $(CXX) $(CXXFLAGS) $< +$O/EnumFormatEtc.o: ../../UI/FileManager/EnumFormatEtc.cpp + $(CXX) $(CXXFLAGS) $< +$O/ExtractCallback.o: ../../UI/FileManager/ExtractCallback.cpp + $(CXX) $(CXXFLAGS) $< +$O/FileFolderPluginOpen.o: ../../UI/FileManager/FileFolderPluginOpen.cpp + $(CXX) $(CXXFLAGS) $< +$O/FilePlugins.o: ../../UI/FileManager/FilePlugins.cpp + $(CXX) $(CXXFLAGS) $< +$O/FM.o: ../../UI/FileManager/FM.cpp + $(CXX) $(CXXFLAGS) $< +$O/FoldersPage.o: ../../UI/FileManager/FoldersPage.cpp + $(CXX) $(CXXFLAGS) $< +$O/FormatUtils.o: ../../UI/FileManager/FormatUtils.cpp + $(CXX) $(CXXFLAGS) $< +$O/FSDrives.o: ../../UI/FileManager/FSDrives.cpp + $(CXX) $(CXXFLAGS) $< +$O/FSFolder.o: ../../UI/FileManager/FSFolder.cpp + $(CXX) $(CXXFLAGS) $< +$O/FSFolderCopy.o: ../../UI/FileManager/FSFolderCopy.cpp + $(CXX) $(CXXFLAGS) $< +$O/HelpUtils.o: ../../UI/FileManager/HelpUtils.cpp + $(CXX) $(CXXFLAGS) $< +$O/LangPage.o: ../../UI/FileManager/LangPage.cpp + $(CXX) $(CXXFLAGS) $< +$O/LangUtils.o: ../../UI/FileManager/LangUtils.cpp + $(CXX) $(CXXFLAGS) $< +$O/LinkDialog.o: ../../UI/FileManager/LinkDialog.cpp + $(CXX) $(CXXFLAGS) $< +$O/ListViewDialog.o: ../../UI/FileManager/ListViewDialog.cpp + $(CXX) $(CXXFLAGS) $< +$O/MenuPage.o: ../../UI/FileManager/MenuPage.cpp + $(CXX) $(CXXFLAGS) $< +$O/MessagesDialog.o: ../../UI/FileManager/MessagesDialog.cpp + $(CXX) $(CXXFLAGS) $< +$O/MyLoadMenu.o: ../../UI/FileManager/MyLoadMenu.cpp + $(CXX) $(CXXFLAGS) $< +$O/NetFolder.o: ../../UI/FileManager/NetFolder.cpp + $(CXX) $(CXXFLAGS) $< +$O/OpenCallback.o: ../../UI/FileManager/OpenCallback.cpp + $(CXX) $(CXXFLAGS) $< +$O/OptionsDialog.o: ../../UI/FileManager/OptionsDialog.cpp + $(CXX) $(CXXFLAGS) $< +$O/OverwriteDialog.o: ../../UI/FileManager/OverwriteDialog.cpp + $(CXX) $(CXXFLAGS) $< +$O/Panel.o: ../../UI/FileManager/Panel.cpp + $(CXX) $(CXXFLAGS) $< +$O/PanelCopy.o: ../../UI/FileManager/PanelCopy.cpp + $(CXX) $(CXXFLAGS) $< +$O/PanelCrc.o: ../../UI/FileManager/PanelCrc.cpp + $(CXX) $(CXXFLAGS) $< +$O/PanelDrag.o: ../../UI/FileManager/PanelDrag.cpp + $(CXX) $(CXXFLAGS) $< +$O/PanelFolderChange.o: ../../UI/FileManager/PanelFolderChange.cpp + $(CXX) $(CXXFLAGS) $< +$O/PanelItemOpen.o: ../../UI/FileManager/PanelItemOpen.cpp + $(CXX) $(CXXFLAGS) $< +$O/PanelItems.o: ../../UI/FileManager/PanelItems.cpp + $(CXX) $(CXXFLAGS) $< +$O/PanelKey.o: ../../UI/FileManager/PanelKey.cpp + $(CXX) $(CXXFLAGS) $< +$O/PanelListNotify.o: ../../UI/FileManager/PanelListNotify.cpp + $(CXX) $(CXXFLAGS) $< +$O/PanelMenu.o: ../../UI/FileManager/PanelMenu.cpp + $(CXX) $(CXXFLAGS) $< +$O/PanelOperations.o: ../../UI/FileManager/PanelOperations.cpp + $(CXX) $(CXXFLAGS) $< +$O/PanelSelect.o: ../../UI/FileManager/PanelSelect.cpp + $(CXX) $(CXXFLAGS) $< +$O/PanelSort.o: ../../UI/FileManager/PanelSort.cpp + $(CXX) $(CXXFLAGS) $< +$O/PanelSplitFile.o: ../../UI/FileManager/PanelSplitFile.cpp + $(CXX) $(CXXFLAGS) $< +$O/PasswordDialog.o: ../../UI/FileManager/PasswordDialog.cpp + $(CXX) $(CXXFLAGS) $< +$O/ProgramLocation.o: ../../UI/FileManager/ProgramLocation.cpp + $(CXX) $(CXXFLAGS) $< +$O/ProgressDialog.o: ../../UI/FileManager/ProgressDialog.cpp + $(CXX) $(CXXFLAGS) $< +$O/ProgressDialog2.o: ../../UI/FileManager/ProgressDialog2.cpp + $(CXX) $(CXXFLAGS) $< +$O/PropertyName.o: ../../UI/FileManager/PropertyName.cpp + $(CXX) $(CXXFLAGS) $< +$O/RegistryAssociations.o: ../../UI/FileManager/RegistryAssociations.cpp + $(CXX) $(CXXFLAGS) $< +$O/RegistryPlugins.o: ../../UI/FileManager/RegistryPlugins.cpp + $(CXX) $(CXXFLAGS) $< +$O/RegistryUtils.o: ../../UI/FileManager/RegistryUtils.cpp + $(CXX) $(CXXFLAGS) $< +$O/RootFolder.o: ../../UI/FileManager/RootFolder.cpp + $(CXX) $(CXXFLAGS) $< +$O/SettingsPage.o: ../../UI/FileManager/SettingsPage.cpp + $(CXX) $(CXXFLAGS) $< +$O/SplitDialog.o: ../../UI/FileManager/SplitDialog.cpp + $(CXX) $(CXXFLAGS) $< +$O/SplitUtils.o: ../../UI/FileManager/SplitUtils.cpp + $(CXX) $(CXXFLAGS) $< +$O/StringUtils.o: ../../UI/FileManager/StringUtils.cpp + $(CXX) $(CXXFLAGS) $< +$O/SysIconUtils.o: ../../UI/FileManager/SysIconUtils.cpp + $(CXX) $(CXXFLAGS) $< +$O/SystemPage.o: ../../UI/FileManager/SystemPage.cpp + $(CXX) $(CXXFLAGS) $< +$O/TextPairs.o: ../../UI/FileManager/TextPairs.cpp + $(CXX) $(CXXFLAGS) $< +$O/UpdateCallback100.o: ../../UI/FileManager/UpdateCallback100.cpp + $(CXX) $(CXXFLAGS) $< +$O/VerCtrl.o: ../../UI/FileManager/VerCtrl.cpp + $(CXX) $(CXXFLAGS) $< +$O/ViewSettings.o: ../../UI/FileManager/ViewSettings.cpp + $(CXX) $(CXXFLAGS) $< + +$O/SfxCon.o: ../../Bundles/SFXCon/SfxCon.cpp + $(CXX) $(CXXFLAGS) $< + +$O/$(FILE_IO).o: ../../../$(FILE_IO_2).cpp + $(CXX) $(CXXFLAGS) $< + + + + + + +$O/7zAlloc.o: ../../../../C/7zAlloc.c + $(CC) $(CFLAGS) $< +$O/7zArcIn.o: ../../../../C/7zArcIn.c + $(CC) $(CFLAGS) $< +$O/7zBuf.o: ../../../../C/7zBuf.c + $(CC) $(CFLAGS) $< +$O/7zBuf2.o: ../../../../C/7zBuf2.c + $(CC) $(CFLAGS) $< +$O/7zCrc.o: ../../../../C/7zCrc.c + $(CC) $(CFLAGS) $< +$O/7zDec.o: ../../../../C/7zDec.c + $(CC) $(CFLAGS) $< +$O/7zFile.o: ../../../../C/7zFile.c + $(CC) $(CFLAGS) $< +$O/7zStream.o: ../../../../C/7zStream.c + $(CC) $(CFLAGS) $< +$O/Aes.o: ../../../../C/Aes.c + $(CC) $(CFLAGS) $< +$O/Alloc.o: ../../../../C/Alloc.c + $(CC) $(CFLAGS) $< +$O/Bcj2.o: ../../../../C/Bcj2.c + $(CC) $(CFLAGS) $< +$O/Bcj2Enc.o: ../../../../C/Bcj2Enc.c + $(CC) $(CFLAGS) $< +$O/Blake2s.o: ../../../../C/Blake2s.c + $(CC) $(CFLAGS) $< +$O/Bra.o: ../../../../C/Bra.c + $(CC) $(CFLAGS) $< +$O/Bra86.o: ../../../../C/Bra86.c + $(CC) $(CFLAGS) $< +$O/BraIA64.o: ../../../../C/BraIA64.c + $(CC) $(CFLAGS) $< +$O/BwtSort.o: ../../../../C/BwtSort.c + $(CC) $(CFLAGS) $< + +$O/CpuArch.o: ../../../../C/CpuArch.c + $(CC) $(CFLAGS) $< +$O/Delta.o: ../../../../C/Delta.c + $(CC) $(CFLAGS) $< +$O/DllSecur.o: ../../../../C/DllSecur.c + $(CC) $(CFLAGS) $< +$O/HuffEnc.o: ../../../../C/HuffEnc.c + $(CC) $(CFLAGS) $< +$O/LzFind.o: ../../../../C/LzFind.c + $(CC) $(CFLAGS) $< + +# ifdef MT_FILES +$O/LzFindMt.o: ../../../../C/LzFindMt.c + $(CC) $(CFLAGS) $< + +$O/Threads.o: ../../../../C/Threads.c + $(CC) $(CFLAGS) $< +# endif + +$O/LzmaEnc.o: ../../../../C/LzmaEnc.c + $(CC) $(CFLAGS) $< +$O/Lzma86Dec.o: ../../../../C/Lzma86Dec.c + $(CC) $(CFLAGS) $< +$O/Lzma86Enc.o: ../../../../C/Lzma86Enc.c + $(CC) $(CFLAGS) $< +$O/Lzma2Dec.o: ../../../../C/Lzma2Dec.c + $(CC) $(CFLAGS) $< +$O/Lzma2DecMt.o: ../../../../C/Lzma2DecMt.c + $(CC) $(CFLAGS) $< +$O/Lzma2Enc.o: ../../../../C/Lzma2Enc.c + $(CC) $(CFLAGS) $< +$O/LzmaLib.o: ../../../../C/LzmaLib.c + $(CC) $(CFLAGS) $< +$O/MtCoder.o: ../../../../C/MtCoder.c + $(CC) $(CFLAGS) $< +$O/MtDec.o: ../../../../C/MtDec.c + $(CC) $(CFLAGS) $< +$O/Ppmd7.o: ../../../../C/Ppmd7.c + $(CC) $(CFLAGS) $< +$O/Ppmd7aDec.o: ../../../../C/Ppmd7aDec.c + $(CC) $(CFLAGS) $< +$O/Ppmd7Dec.o: ../../../../C/Ppmd7Dec.c + $(CC) $(CFLAGS) $< +$O/Ppmd7Enc.o: ../../../../C/Ppmd7Enc.c + $(CC) $(CFLAGS) $< +$O/Ppmd8.o: ../../../../C/Ppmd8.c + $(CC) $(CFLAGS) $< +$O/Ppmd8Dec.o: ../../../../C/Ppmd8Dec.c + $(CC) $(CFLAGS) $< +$O/Ppmd8Enc.o: ../../../../C/Ppmd8Enc.c + $(CC) $(CFLAGS) $< +$O/Sha1.o: ../../../../C/Sha1.c + $(CC) $(CFLAGS) $< +$O/Sha256.o: ../../../../C/Sha256.c + $(CC) $(CFLAGS) $< +$O/Sort.o: ../../../../C/Sort.c + $(CC) $(CFLAGS) $< +$O/SwapBytes.o: ../../../../C/SwapBytes.c + $(CC) $(CFLAGS) $< +$O/Xz.o: ../../../../C/Xz.c + $(CC) $(CFLAGS) $< +$O/XzCrc64.o: ../../../../C/XzCrc64.c + $(CC) $(CFLAGS) $< +$O/XzDec.o: ../../../../C/XzDec.c + $(CC) $(CFLAGS) $< +$O/XzEnc.o: ../../../../C/XzEnc.c + $(CC) $(CFLAGS) $< +$O/XzIn.o: ../../../../C/XzIn.c + $(CC) $(CFLAGS) $< + + +ifdef USE_ASM +ifdef IS_X64 +USE_X86_ASM=1 +USE_X64_ASM=1 +else +ifdef IS_X86 +USE_X86_ASM=1 +endif +endif +endif + +ifdef USE_X86_ASM +$O/7zCrcOpt.o: ../../../../Asm/x86/7zCrcOpt.asm + $(MY_ASM) $(AFLAGS) $< +$O/XzCrc64Opt.o: ../../../../Asm/x86/XzCrc64Opt.asm + $(MY_ASM) $(AFLAGS) $< +$O/Sha1Opt.o: ../../../../Asm/x86/Sha1Opt.asm + $(MY_ASM) $(AFLAGS) $< +$O/Sha256Opt.o: ../../../../Asm/x86/Sha256Opt.asm + $(MY_ASM) $(AFLAGS) $< + +ifndef USE_JWASM +USE_X86_ASM_AES=1 +endif + +else +$O/7zCrcOpt.o: ../../../../C/7zCrcOpt.c + $(CC) $(CFLAGS) $< +$O/XzCrc64Opt.o: ../../../../C/XzCrc64Opt.c + $(CC) $(CFLAGS) $< +$O/Sha1Opt.o: ../../../../C/Sha1Opt.c + $(CC) $(CFLAGS) $< +$O/Sha256Opt.o: ../../../../C/Sha256Opt.c + $(CC) $(CFLAGS) $< +endif + + +ifdef USE_X86_ASM_AES +$O/AesOpt.o: ../../../../Asm/x86/AesOpt.asm + $(MY_ASM) $(AFLAGS) $< +else +$O/AesOpt.o: ../../../../C/AesOpt.c + $(CC) $(CFLAGS) $< +endif + + +ifdef USE_X64_ASM +$O/LzFindOpt.o: ../../../../Asm/x86/LzFindOpt.asm + $(MY_ASM) $(AFLAGS) $< +else +$O/LzFindOpt.o: ../../../../C/LzFindOpt.c + $(CC) $(CFLAGS) $< +endif + +ifdef USE_LZMA_DEC_ASM + +ifdef IS_X64 +$O/LzmaDecOpt.o: ../../../../Asm/x86/LzmaDecOpt.asm + $(MY_ASM) $(AFLAGS) $< +endif + +ifdef IS_ARM64 +$O/LzmaDecOpt.o: ../../../../Asm/arm64/LzmaDecOpt.S ../../../../Asm/arm64/7zAsm.S + $(CC) $(CFLAGS) $< +endif + +$O/LzmaDec.o: ../../../../C/LzmaDec.c + $(CC) $(CFLAGS) -DZ7_LZMA_DEC_OPT $< + +else + +$O/LzmaDec.o: ../../../../C/LzmaDec.c + $(CC) $(CFLAGS) $< + +endif + + + + +$O/7zMain.o: ../../../../C/Util/7z/7zMain.c + $(CC) $(CFLAGS) $< +$O/LzmaUtil.o: ../../../../C/Util/Lzma/LzmaUtil.c + $(CC) $(CFLAGS) $< + +ifneq ($(CC), xlc) +SHOW_PREDEF=-dM +else +SHOW_PREDEF= -qshowmacros=pre +endif + +predef_cc: + $(CC) $(CFLAGS) -E $(SHOW_PREDEF) ../../../../C/CpuArch.c > predef_cc_log +# $(CC) $(CFLAGS) -E -dM - < /dev/null +predef_cxx: + $(CXX) $(CFLAGS) -E $(SHOW_PREDEF) ../../../Common/CrcReg.cpp > predef_cxx_log + +predef: predef_cc predef_cxx + + +clean: + -$(DEL_OBJ_EXE) diff --git a/3rdparty/lzma/CPP/7zip/Aes.mak b/3rdparty/lzma/CPP/7zip/Aes.mak index c5a58f28f4a..7d8da2d8101 100644 --- a/3rdparty/lzma/CPP/7zip/Aes.mak +++ b/3rdparty/lzma/CPP/7zip/Aes.mak @@ -1,7 +1,10 @@ C_OBJS = $(C_OBJS) \ $O\Aes.obj -!IF "$(CPU)" != "IA64" && "$(CPU)" != "MIPS" && "$(CPU)" != "ARM" +!IF defined(USE_C_AES) || "$(PLATFORM)" == "arm" || "$(PLATFORM)" == "arm64" +C_OBJS = $(C_OBJS) \ + $O\AesOpt.obj +!ELSEIF "$(PLATFORM)" != "ia64" && "$(PLATFORM)" != "mips" && "$(PLATFORM)" != "arm" && "$(PLATFORM)" != "arm64" ASM_OBJS = $(ASM_OBJS) \ $O\AesOpt.obj !ENDIF diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zCompressionMode.h b/3rdparty/lzma/CPP/7zip/Archive/7z/7zCompressionMode.h index 8105ff0413d..ac1f6ad14ca 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zCompressionMode.h +++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zCompressionMode.h @@ -1,7 +1,7 @@ // 7zCompressionMode.h -#ifndef __7Z_COMPRESSION_MODE_H -#define __7Z_COMPRESSION_MODE_H +#ifndef ZIP7_INC_7Z_COMPRESSION_MODE_H +#define ZIP7_INC_7Z_COMPRESSION_MODE_H #include "../../Common/MethodId.h" #include "../../Common/MethodProps.h" @@ -13,7 +13,11 @@ struct CMethodFull: public CMethodProps { CMethodId Id; UInt32 NumStreams; + int CodecIndex; + UInt32 NumThreads; + bool Set_NumThreads; + CMethodFull(): CodecIndex(-1), NumThreads(1), Set_NumThreads(false) {} bool IsSimpleCoder() const { return NumStreams == 1; } }; @@ -49,24 +53,37 @@ struct CCompressionMethodMode bool DefaultMethod_was_Inserted; bool Filter_was_Inserted; - #ifndef _7ZIP_ST + #ifndef Z7_ST UInt32 NumThreads; + bool NumThreads_WasForced; bool MultiThreadMixer; #endif + + UInt64 MemoryUsageLimit; + bool MemoryUsageLimit_WasSet; bool PasswordIsDefined; - UString Password; + UString Password; // _Wipe bool IsEmpty() const { return (Methods.IsEmpty() && !PasswordIsDefined); } CCompressionMethodMode(): - DefaultMethod_was_Inserted(false), - Filter_was_Inserted(false), - PasswordIsDefined(false) - #ifndef _7ZIP_ST + DefaultMethod_was_Inserted(false) + , Filter_was_Inserted(false) + #ifndef Z7_ST , NumThreads(1) + , NumThreads_WasForced(false) , MultiThreadMixer(true) #endif + , MemoryUsageLimit((UInt64)1 << 30) + , MemoryUsageLimit_WasSet(false) + , PasswordIsDefined(false) {} + +#ifdef Z7_CPP_IS_SUPPORTED_default + CCompressionMethodMode(const CCompressionMethodMode &) = default; + CCompressionMethodMode& operator =(const CCompressionMethodMode &) = default; +#endif + ~CCompressionMethodMode() { Password.Wipe_and_Empty(); } }; }} diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zDecode.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zDecode.cpp index b0d6dd838aa..5420dcee30d 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zDecode.cpp +++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zDecode.cpp @@ -5,25 +5,23 @@ #include "../../Common/LimitedStreams.h" #include "../../Common/ProgressUtils.h" #include "../../Common/StreamObjects.h" +#include "../../Common/StreamUtils.h" #include "7zDecode.h" namespace NArchive { namespace N7z { -class CDecProgress: - public ICompressProgressInfo, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_1( + CDecProgress + , ICompressProgressInfo +) CMyComPtr<ICompressProgressInfo> _progress; public: CDecProgress(ICompressProgressInfo *progress): _progress(progress) {} - - MY_UNKNOWN_IMP1(ICompressProgressInfo) - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); }; -STDMETHODIMP CDecProgress::SetRatioInfo(const UInt64 * /* inSize */, const UInt64 *outSize) +Z7_COM7F_IMF(CDecProgress::SetRatioInfo(const UInt64 * /* inSize */, const UInt64 *outSize)) { return _progress->SetRatioInfo(NULL, outSize); } @@ -110,20 +108,23 @@ static bool AreBindInfoExEqual(const CBindInfoEx &a1, const CBindInfoEx &a2) } CDecoder::CDecoder(bool useMixerMT): - _bindInfoPrev_Defined(false), - _useMixerMT(useMixerMT) -{} + _bindInfoPrev_Defined(false) +{ + #if defined(USE_MIXER_ST) && defined(USE_MIXER_MT) + _useMixerMT = useMixerMT; + #else + UNUSED_VAR(useMixerMT) + #endif +} -struct CLockedInStream: - public IUnknown, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_0( + CLockedInStream +) +public: CMyComPtr<IInStream> Stream; UInt64 Pos; - MY_UNKNOWN_IMP - #ifdef USE_MIXER_MT NWindows::NSynchronization::CCriticalSection CriticalSection; #endif @@ -132,10 +133,10 @@ struct CLockedInStream: #ifdef USE_MIXER_MT -class CLockedSequentialInStreamMT: - public ISequentialInStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_1( + CLockedSequentialInStreamMT + , ISequentialInStream +) CLockedInStream *_glob; UInt64 _pos; CMyComPtr<IUnknown> _globRef; @@ -146,24 +147,20 @@ public: _glob = lockedInStream; _pos = startPos; } - - MY_UNKNOWN_IMP1(ISequentialInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); }; -STDMETHODIMP CLockedSequentialInStreamMT::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CLockedSequentialInStreamMT::Read(void *data, UInt32 size, UInt32 *processedSize)) { NWindows::NSynchronization::CCriticalSectionLock lock(_glob->CriticalSection); if (_pos != _glob->Pos) { - RINOK(_glob->Stream->Seek(_pos, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(_glob->Stream, _pos)) _glob->Pos = _pos; } UInt32 realProcessedSize = 0; - HRESULT res = _glob->Stream->Read(data, size, &realProcessedSize); + const HRESULT res = _glob->Stream->Read(data, size, &realProcessedSize); _pos += realProcessedSize; _glob->Pos = _pos; if (processedSize) @@ -176,10 +173,10 @@ STDMETHODIMP CLockedSequentialInStreamMT::Read(void *data, UInt32 size, UInt32 * #ifdef USE_MIXER_ST -class CLockedSequentialInStreamST: - public ISequentialInStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_1( + CLockedSequentialInStreamST + , ISequentialInStream +) CLockedInStream *_glob; UInt64 _pos; CMyComPtr<IUnknown> _globRef; @@ -190,22 +187,18 @@ public: _glob = lockedInStream; _pos = startPos; } - - MY_UNKNOWN_IMP1(ISequentialInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); }; -STDMETHODIMP CLockedSequentialInStreamST::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CLockedSequentialInStreamST::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (_pos != _glob->Pos) { - RINOK(_glob->Stream->Seek(_pos, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(_glob->Stream, _pos)) _glob->Pos = _pos; } UInt32 realProcessedSize = 0; - HRESULT res = _glob->Stream->Read(data, size, &realProcessedSize); + const HRESULT res = _glob->Stream->Read(data, size, &realProcessedSize); _pos += realProcessedSize; _glob->Pos = _pos; if (processedSize) @@ -226,19 +219,23 @@ HRESULT CDecoder::Decode( , ISequentialOutStream *outStream , ICompressProgressInfo *compressProgress + , ISequentialInStream ** + #ifdef USE_MIXER_ST + inStreamMainRes + #endif - #ifdef USE_MIXER_ST - inStreamMainRes - #endif + , bool &dataAfterEnd_Error - _7Z_DECODER_CRYPRO_VARS_DECL + Z7_7Z_DECODER_CRYPRO_VARS_DECL - #if !defined(_7ZIP_ST) && !defined(_SFX) - , bool mtMode, UInt32 numThreads + #if !defined(Z7_ST) + , bool mtMode, UInt32 numThreads, UInt64 memUsage #endif ) { + dataAfterEnd_Error = false; + const UInt64 *packPositions = &folders.PackPositions[folders.FoStartPackStreamIndex[folderIndex]]; CFolderEx folderInfo; folders.ParseFolderEx(folderIndex, folderInfo); @@ -264,7 +261,7 @@ HRESULT CDecoder::Decode( We don't need to init isEncrypted and passwordIsDefined We must upgrade them only - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO isEncrypted = false; passwordIsDefined = false; #endif @@ -272,6 +269,7 @@ HRESULT CDecoder::Decode( if (!_bindInfoPrev_Defined || !AreBindInfoExEqual(bindInfo, _bindInfoPrev)) { + _bindInfoPrev_Defined = false; _mixerRef.Release(); #ifdef USE_MIXER_MT @@ -295,22 +293,22 @@ HRESULT CDecoder::Decode( #endif } - RINOK(_mixer->SetBindInfo(bindInfo)); + RINOK(_mixer->SetBindInfo(bindInfo)) FOR_VECTOR(i, folderInfo.Coders) { const CCoderInfo &coderInfo = folderInfo.Coders[i]; - #ifndef _SFX + #ifndef Z7_SFX // we don't support RAR codecs here if ((coderInfo.MethodID >> 8) == 0x403) return E_NOTIMPL; #endif CCreatedCoder cod; - RINOK(CreateCoder( + RINOK(CreateCoder_Id( EXTERNAL_CODECS_LOC_VARS - coderInfo.MethodID, false, cod)); + coderInfo.MethodID, false, cod)) if (coderInfo.IsSimpleCoder()) { @@ -328,13 +326,13 @@ HRESULT CDecoder::Decode( // now there is no codec that uses another external codec /* - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo; decoderUnknown.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo); if (setCompressCodecsInfo) { // we must use g_ExternalCodecs also - RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(__externalCodecs->GetCodecs)); + RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(_externalCodecs->GetCodecs)); } #endif */ @@ -344,83 +342,126 @@ HRESULT CDecoder::Decode( _bindInfoPrev_Defined = true; } - _mixer->ReInit(); + RINOK(_mixer->ReInit2()) UInt32 packStreamIndex = 0; UInt32 unpackStreamIndexStart = folders.FoToCoderUnpackSizes[folderIndex]; unsigned i; + #if !defined(Z7_ST) + bool mt_wasUsed = false; + #endif + for (i = 0; i < folderInfo.Coders.Size(); i++) { const CCoderInfo &coderInfo = folderInfo.Coders[i]; IUnknown *decoder = _mixer->GetCoder(i).GetUnknown(); + // now there is no codec that uses another external codec + /* + #ifdef Z7_EXTERNAL_CODECS { - CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties; - decoder->QueryInterface(IID_ICompressSetDecoderProperties2, (void **)&setDecoderProperties); - if (setDecoderProperties) + Z7_DECL_CMyComPtr_QI_FROM(ISetCompressCodecsInfo, + setCompressCodecsInfo, decoder) + if (setCompressCodecsInfo) { - const CByteBuffer &props = coderInfo.Props; - size_t size = props.Size(); - if (size > 0xFFFFFFFF) - return E_NOTIMPL; - HRESULT res = setDecoderProperties->SetDecoderProperties2((const Byte *)props, (UInt32)size); - if (res == E_INVALIDARG) - res = E_NOTIMPL; - RINOK(res); + // we must use g_ExternalCodecs also + RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(_externalCodecs->GetCodecs)) } } + #endif + */ - #if !defined(_7ZIP_ST) && !defined(_SFX) - if (mtMode) + #if !defined(Z7_ST) + if (!mt_wasUsed) { - CMyComPtr<ICompressSetCoderMt> setCoderMt; - decoder->QueryInterface(IID_ICompressSetCoderMt, (void **)&setCoderMt); - if (setCoderMt) + if (mtMode) { - RINOK(setCoderMt->SetNumberOfThreads(numThreads)); + Z7_DECL_CMyComPtr_QI_FROM(ICompressSetCoderMt, + setCoderMt, decoder) + if (setCoderMt) + { + mt_wasUsed = true; + RINOK(setCoderMt->SetNumberOfThreads(numThreads)) + } + } + // if (memUsage != 0) + { + Z7_DECL_CMyComPtr_QI_FROM(ICompressSetMemLimit, + setMemLimit, decoder) + if (setMemLimit) + { + mt_wasUsed = true; + RINOK(setMemLimit->SetMemLimit(memUsage)) + } } } #endif - #ifndef _NO_CRYPTO { - CMyComPtr<ICryptoSetPassword> cryptoSetPassword; - decoder->QueryInterface(IID_ICryptoSetPassword, (void **)&cryptoSetPassword); + Z7_DECL_CMyComPtr_QI_FROM( + ICompressSetDecoderProperties2, + setDecoderProperties, decoder) + const CByteBuffer &props = coderInfo.Props; + const UInt32 size32 = (UInt32)props.Size(); + if (props.Size() != size32) + return E_NOTIMPL; + if (setDecoderProperties) + { + HRESULT res = setDecoderProperties->SetDecoderProperties2((const Byte *)props, size32); + if (res == E_INVALIDARG) + res = E_NOTIMPL; + RINOK(res) + } + else if (size32 != 0) + { + // v23: we fail, if decoder doesn't support properties + return E_NOTIMPL; + } + } + + #ifndef Z7_NO_CRYPTO + { + Z7_DECL_CMyComPtr_QI_FROM( + ICryptoSetPassword, + cryptoSetPassword, decoder) if (cryptoSetPassword) { isEncrypted = true; if (!getTextPassword) return E_NOTIMPL; - CMyComBSTR passwordBSTR; - RINOK(getTextPassword->CryptoGetTextPassword(&passwordBSTR)); + CMyComBSTR_Wipe passwordBSTR; + RINOK(getTextPassword->CryptoGetTextPassword(&passwordBSTR)) passwordIsDefined = true; - password.Empty(); + password.Wipe_and_Empty(); size_t len = 0; if (passwordBSTR) { password = passwordBSTR; len = password.Len(); } - CByteBuffer buffer(len * 2); + CByteBuffer_Wipe buffer(len * 2); for (size_t k = 0; k < len; k++) { - wchar_t c = passwordBSTR[k]; + const wchar_t c = passwordBSTR[k]; ((Byte *)buffer)[k * 2] = (Byte)c; ((Byte *)buffer)[k * 2 + 1] = (Byte)(c >> 8); } - RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, (UInt32)buffer.Size())); + RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, (UInt32)buffer.Size())) } } #endif + bool finishMode = false; { - CMyComPtr<ICompressSetFinishMode> setFinishMode; - decoder->QueryInterface(IID_ICompressSetFinishMode, (void **)&setFinishMode); + Z7_DECL_CMyComPtr_QI_FROM( + ICompressSetFinishMode, + setFinishMode, decoder) if (setFinishMode) { - RINOK(setFinishMode->SetFinishMode(BoolToInt(fullUnpack))); + finishMode = fullUnpack; + RINOK(setFinishMode->SetFinishMode(BoolToUInt(finishMode))) } } @@ -450,7 +491,7 @@ HRESULT CDecoder::Decode( unpackSize : &folders.CoderUnpackSizes[unpackStreamIndexStart + i]; - _mixer->SetCoderInfo(i, unpackSizesPointer, packSizesPointers); + _mixer->SetCoderInfo(i, unpackSizesPointer, packSizesPointers, finishMode); } if (outStream) @@ -463,36 +504,49 @@ HRESULT CDecoder::Decode( CLockedInStream *lockedInStreamSpec = new CLockedInStream; CMyComPtr<IUnknown> lockedInStream = lockedInStreamSpec; - bool needMtLock = false; + #ifdef USE_MIXER_MT + #ifdef USE_MIXER_ST + bool needMtLock = _useMixerMT; + #endif + #endif if (folderInfo.PackStreams.Size() > 1) { // lockedInStream.Pos = (UInt64)(Int64)-1; - // RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &lockedInStream.Pos)); - RINOK(inStream->Seek(startPos + packPositions[0], STREAM_SEEK_SET, &lockedInStreamSpec->Pos)); + // RINOK(InStream_GetPos(inStream, lockedInStream.Pos)) + RINOK(inStream->Seek((Int64)(startPos + packPositions[0]), STREAM_SEEK_SET, &lockedInStreamSpec->Pos)) lockedInStreamSpec->Stream = inStream; + #ifdef USE_MIXER_MT #ifdef USE_MIXER_ST - if (_mixer->IsThere_ExternalCoder_in_PackTree(_mixer->MainCoderIndex)) - #endif + /* + For ST-mixer mode: + If parallel input stream reading from pack streams is possible, + we must use MT-lock for packed streams. + Internal decoders in 7-Zip will not read pack streams in parallel in ST-mixer mode. + So we force to needMtLock mode only if there is unknown (external) decoder. + */ + if (!needMtLock && _mixer->IsThere_ExternalCoder_in_PackTree(_mixer->MainCoderIndex)) needMtLock = true; + #endif + #endif } for (unsigned j = 0; j < folderInfo.PackStreams.Size(); j++) { CMyComPtr<ISequentialInStream> packStream; - UInt64 packPos = startPos + packPositions[j]; + const UInt64 packPos = startPos + packPositions[j]; if (folderInfo.PackStreams.Size() == 1) { - RINOK(inStream->Seek(packPos, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(inStream, packPos)) packStream = inStream; } else { #ifdef USE_MIXER_MT #ifdef USE_MIXER_ST - if (_useMixerMT || needMtLock) + if (needMtLock) #endif { CLockedSequentialInStreamMT *lockedStreamImpSpec = new CLockedSequentialInStreamMT; @@ -518,7 +572,7 @@ HRESULT CDecoder::Decode( streamSpec->Init(packPositions[j + 1] - packPositions[j]); } - unsigned num = inStreams.Size(); + const unsigned num = inStreams.Size(); CObjArray<ISequentialInStream *> inStreamPointers(num); for (i = 0; i < num; i++) inStreamPointers[i] = inStreams[i]; @@ -530,7 +584,9 @@ HRESULT CDecoder::Decode( progress2 = new CDecProgress(compressProgress); ISequentialOutStream *outStreamPointer = outStream; - return _mixer->Code(inStreamPointers, &outStreamPointer, progress2 ? (ICompressProgressInfo *)progress2 : compressProgress); + return _mixer->Code(inStreamPointers, &outStreamPointer, + progress2 ? (ICompressProgressInfo *)progress2 : compressProgress, + dataAfterEnd_Error); } #ifdef USE_MIXER_ST diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zDecode.h b/3rdparty/lzma/CPP/7zip/Archive/7z/7zDecode.h index 5b729f6c86d..ee9d9c255b1 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zDecode.h +++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zDecode.h @@ -1,7 +1,7 @@ // 7zDecode.h -#ifndef __7Z_DECODE_H -#define __7Z_DECODE_H +#ifndef ZIP7_INC_7Z_DECODE_H +#define ZIP7_INC_7Z_DECODE_H #include "../Common/CoderMixer2.h" @@ -24,10 +24,13 @@ struct CBindInfoEx: public NCoderMixer2::CBindInfo class CDecoder { bool _bindInfoPrev_Defined; + #ifdef USE_MIXER_ST + #ifdef USE_MIXER_MT + bool _useMixerMT; + #endif + #endif CBindInfoEx _bindInfoPrev; - bool _useMixerMT; - #ifdef USE_MIXER_ST NCoderMixer2::CMixerST *_mixerST; #endif @@ -53,12 +56,14 @@ public: , ISequentialOutStream *outStream , ICompressProgressInfo *compressProgress + , ISequentialInStream **inStreamMainRes + , bool &dataAfterEnd_Error - _7Z_DECODER_CRYPRO_VARS_DECL + Z7_7Z_DECODER_CRYPRO_VARS_DECL - #if !defined(_7ZIP_ST) && !defined(_SFX) - , bool mtMode, UInt32 numThreads + #if !defined(Z7_ST) + , bool mtMode, UInt32 numThreads, UInt64 memUsage #endif ); }; diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zEncode.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zEncode.cpp index 97e9ad7adb8..78c91cfa28b 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zEncode.cpp +++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zEncode.cpp @@ -2,6 +2,8 @@ #include "StdAfx.h" +#include "../../../Common/ComTry.h" + #include "../../Common/CreateCoder.h" #include "../../Common/FilterCoder.h" #include "../../Common/LimitedStreams.h" @@ -19,11 +21,11 @@ void CEncoder::InitBindConv() { unsigned numIn = _bindInfo.Coders.Size(); - _SrcIn_to_DestOut.ClearAndSetSize(numIn); - _DestOut_to_SrcIn.ClearAndSetSize(numIn); + SrcIn_to_DestOut.ClearAndSetSize(numIn); + DestOut_to_SrcIn.ClearAndSetSize(numIn); unsigned numOut = _bindInfo.GetNum_Bonds_and_PackStreams(); - _SrcOut_to_DestIn.ClearAndSetSize(numOut); + SrcOut_to_DestIn.ClearAndSetSize(numOut); // _DestIn_to_SrcOut.ClearAndSetSize(numOut); UInt32 destIn = 0; @@ -38,15 +40,15 @@ void CEncoder::InitBindConv() numIn--; numOut -= coder.NumStreams; - _SrcIn_to_DestOut[numIn] = destOut; - _DestOut_to_SrcIn[destOut] = numIn; + SrcIn_to_DestOut[numIn] = destOut; + DestOut_to_SrcIn[destOut] = numIn; destOut++; for (UInt32 j = 0; j < coder.NumStreams; j++, destIn++) { UInt32 index = numOut + j; - _SrcOut_to_DestIn[index] = destIn; + SrcOut_to_DestIn[index] = destIn; // _DestIn_to_SrcOut[destIn] = index; } } @@ -62,8 +64,8 @@ void CEncoder::SetFolder(CFolder &folder) { CBond &fb = folder.Bonds[i]; const NCoderMixer2::CBond &mixerBond = _bindInfo.Bonds[_bindInfo.Bonds.Size() - 1 - i]; - fb.PackIndex = _SrcOut_to_DestIn[mixerBond.PackIndex]; - fb.UnpackIndex = _SrcIn_to_DestOut[mixerBond.UnpackIndex]; + fb.PackIndex = SrcOut_to_DestIn[mixerBond.PackIndex]; + fb.UnpackIndex = SrcIn_to_DestOut[mixerBond.UnpackIndex]; } folder.Coders.SetSize(_bindInfo.Coders.Size()); @@ -81,15 +83,16 @@ void CEncoder::SetFolder(CFolder &folder) folder.PackStreams.SetSize(_bindInfo.PackStreams.Size()); for (i = 0; i < _bindInfo.PackStreams.Size(); i++) - folder.PackStreams[i] = _SrcOut_to_DestIn[_bindInfo.PackStreams[i]]; + folder.PackStreams[i] = SrcOut_to_DestIn[_bindInfo.PackStreams[i]]; } static HRESULT SetCoderProps2(const CProps &props, const UInt64 *dataSizeReduce, IUnknown *coder) { - CMyComPtr<ICompressSetCoderProperties> setCoderProperties; - coder->QueryInterface(IID_ICompressSetCoderProperties, (void **)&setCoderProperties); + Z7_DECL_CMyComPtr_QI_FROM( + ICompressSetCoderProperties, + setCoderProperties, coder) if (setCoderProperties) return props.SetCoderProps(setCoderProperties, dataSizeReduce); return props.AreThereNonOptionalProps() ? E_INVALIDARG : S_OK; @@ -103,11 +106,11 @@ void CMtEncMultiProgress::Init(ICompressProgressInfo *progress) OutSize = 0; } -STDMETHODIMP CMtEncMultiProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */) +Z7_COM7F_IMF(CMtEncMultiProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */)) { UInt64 outSize2; { - #ifndef _7ZIP_ST + #ifndef Z7_ST NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection); #endif outSize2 = OutSize; @@ -146,7 +149,7 @@ HRESULT CEncoder::CreateMixerCoder( #endif } - RINOK(_mixer->SetBindInfo(_bindInfo)); + RINOK(_mixer->SetBindInfo(_bindInfo)) FOR_VECTOR (m, _options.Methods) { @@ -154,29 +157,46 @@ HRESULT CEncoder::CreateMixerCoder( CCreatedCoder cod; - RINOK(CreateCoder( + if (methodFull.CodecIndex >= 0) + { + RINOK(CreateCoder_Index( + EXTERNAL_CODECS_LOC_VARS + (unsigned)methodFull.CodecIndex, true, cod)) + } + else + { + RINOK(CreateCoder_Id( EXTERNAL_CODECS_LOC_VARS - methodFull.Id, true, cod)); + methodFull.Id, true, cod)) + } - if (cod.NumStreams != methodFull.NumStreams) - return E_FAIL; if (!cod.Coder && !cod.Coder2) + { + return E_NOTIMPL; // unsupported method, if encoder + // return E_FAIL; + } + + if (cod.NumStreams != methodFull.NumStreams) return E_FAIL; CMyComPtr<IUnknown> encoderCommon = cod.Coder ? (IUnknown *)cod.Coder : (IUnknown *)cod.Coder2; - #ifndef _7ZIP_ST + #ifndef Z7_ST + if (methodFull.Set_NumThreads) { CMyComPtr<ICompressSetCoderMt> setCoderMt; encoderCommon.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt); if (setCoderMt) { - RINOK(setCoderMt->SetNumberOfThreads(_options.NumThreads)); + RINOK(setCoderMt->SetNumberOfThreads( + /* _options.NumThreads */ + methodFull.NumThreads + )) } } #endif - RINOK(SetCoderProps2(methodFull, inSizeForReduce, encoderCommon)); + RINOK(SetCoderProps2(methodFull, inSizeForReduce, encoderCommon)) /* CMyComPtr<ICryptoResetSalt> resetSalt; @@ -189,13 +209,13 @@ HRESULT CEncoder::CreateMixerCoder( // now there is no codec that uses another external codec /* - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo; encoderCommon.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo); if (setCompressCodecsInfo) { // we must use g_ExternalCodecs also - RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(__externalCodecs->GetCodecs)); + RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(_externalCodecs->GetCodecs)); } #endif */ @@ -206,14 +226,14 @@ HRESULT CEncoder::CreateMixerCoder( if (cryptoSetPassword) { const unsigned sizeInBytes = _options.Password.Len() * 2; - CByteBuffer buffer(sizeInBytes); + CByteBuffer_Wipe buffer(sizeInBytes); for (unsigned i = 0; i < _options.Password.Len(); i++) { wchar_t c = _options.Password[i]; ((Byte *)buffer)[i * 2] = (Byte)c; ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8); } - RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, (UInt32)sizeInBytes)); + RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, (UInt32)sizeInBytes)) } _mixer->AddCoder(cod); @@ -223,84 +243,94 @@ HRESULT CEncoder::CreateMixerCoder( -class CSequentialOutTempBufferImp2: - public ISequentialOutStream, - public CMyUnknownImp -{ - CInOutTempBuffer *_buf; +Z7_CLASS_IMP_COM_1( + CSequentialOutTempBufferImp2 + , ISequentialOutStream +) public: - CMtEncMultiProgress *_mtProgresSpec; + CInOutTempBuffer TempBuffer; + CMtEncMultiProgress *_mtProgressSpec; - CSequentialOutTempBufferImp2(): _buf(0), _mtProgresSpec(NULL) {} - void Init(CInOutTempBuffer *buffer) { _buf = buffer; } - MY_UNKNOWN_IMP1(ISequentialOutStream) - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + CSequentialOutTempBufferImp2(): _mtProgressSpec(NULL) {} }; -STDMETHODIMP CSequentialOutTempBufferImp2::Write(const void *data, UInt32 size, UInt32 *processed) +Z7_COM7F_IMF(CSequentialOutTempBufferImp2::Write(const void *data, UInt32 size, UInt32 *processed)) { - if (!_buf->Write(data, size)) - { - if (processed) - *processed = 0; - return E_FAIL; - } + COM_TRY_BEGIN + if (processed) + *processed = 0; + RINOK(TempBuffer.Write_HRESULT(data, size)) if (processed) *processed = size; - if (_mtProgresSpec) - _mtProgresSpec->AddOutSize(size); + if (_mtProgressSpec) + _mtProgressSpec->AddOutSize(size); return S_OK; + COM_TRY_END } -class CSequentialOutMtNotify: - public ISequentialOutStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_1( + CSequentialOutMtNotify + , ISequentialOutStream +) public: CMyComPtr<ISequentialOutStream> _stream; - CMtEncMultiProgress *_mtProgresSpec; + CMtEncMultiProgress *_mtProgressSpec; - CSequentialOutMtNotify(): _mtProgresSpec(NULL) {} - MY_UNKNOWN_IMP1(ISequentialOutStream) - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + CSequentialOutMtNotify(): _mtProgressSpec(NULL) {} }; -STDMETHODIMP CSequentialOutMtNotify::Write(const void *data, UInt32 size, UInt32 *processed) +Z7_COM7F_IMF(CSequentialOutMtNotify::Write(const void *data, UInt32 size, UInt32 *processed)) { UInt32 realProcessed = 0; HRESULT res = _stream->Write(data, size, &realProcessed); if (processed) *processed = realProcessed; - if (_mtProgresSpec) - _mtProgresSpec->AddOutSize(size); + if (_mtProgressSpec) + _mtProgressSpec->AddOutSize(size); return res; } +static HRESULT FillProps_from_Coder(IUnknown *coder, CByteBuffer &props) +{ + Z7_DECL_CMyComPtr_QI_FROM( + ICompressWriteCoderProperties, + writeCoderProperties, coder) + if (writeCoderProperties) + { + CDynBufSeqOutStream *outStreamSpec = new CDynBufSeqOutStream; + CMyComPtr<ISequentialOutStream> dynOutStream(outStreamSpec); + outStreamSpec->Init(); + RINOK(writeCoderProperties->WriteCoderProperties(dynOutStream)) + outStreamSpec->CopyToBuffer(props); + } + else + props.Free(); + return S_OK; +} -HRESULT CEncoder::Encode( +HRESULT CEncoder::Encode1( DECL_EXTERNAL_CODECS_LOC_VARS ISequentialInStream *inStream, // const UInt64 *inStreamSize, const UInt64 *inSizeForReduce, + UInt64 expectedDataSize, CFolder &folderItem, - CRecordVector<UInt64> &coderUnpackSizes, - UInt64 &unpackSize, + // CRecordVector<UInt64> &coderUnpackSizes, + // UInt64 &unpackSize, ISequentialOutStream *outStream, CRecordVector<UInt64> &packSizes, ICompressProgressInfo *compressProgress) { - RINOK(EncoderConstr()); + RINOK(EncoderConstr()) if (!_mixerRef) { - RINOK(CreateMixerCoder(EXTERNAL_CODECS_LOC_VARS inSizeForReduce)); + RINOK(CreateMixerCoder(EXTERNAL_CODECS_LOC_VARS inSizeForReduce)) } - _mixer->ReInit(); + RINOK(_mixer->ReInit2()) CMtEncMultiProgress *mtProgressSpec = NULL; CMyComPtr<ICompressProgressInfo> mtProgress; @@ -308,32 +338,23 @@ HRESULT CEncoder::Encode( CSequentialOutMtNotify *mtOutStreamNotifySpec = NULL; CMyComPtr<ISequentialOutStream> mtOutStreamNotify; - CObjectVector<CInOutTempBuffer> inOutTempBuffers; - CObjectVector<CSequentialOutTempBufferImp2 *> tempBufferSpecs; + CRecordVector<CSequentialOutTempBufferImp2 *> tempBufferSpecs; CObjectVector<CMyComPtr<ISequentialOutStream> > tempBuffers; - unsigned numMethods = _bindInfo.Coders.Size(); - unsigned i; for (i = 1; i < _bindInfo.PackStreams.Size(); i++) { - CInOutTempBuffer &iotb = inOutTempBuffers.AddNew(); - iotb.Create(); - iotb.InitWriting(); - } - - for (i = 1; i < _bindInfo.PackStreams.Size(); i++) - { - CSequentialOutTempBufferImp2 *tempBufferSpec = new CSequentialOutTempBufferImp2; + CSequentialOutTempBufferImp2 *tempBufferSpec = new CSequentialOutTempBufferImp2(); CMyComPtr<ISequentialOutStream> tempBuffer = tempBufferSpec; - tempBufferSpec->Init(&inOutTempBuffers[i - 1]); - tempBuffers.Add(tempBuffer); tempBufferSpecs.Add(tempBufferSpec); + tempBuffers.Add(tempBuffer); } + const unsigned numMethods = _bindInfo.Coders.Size(); + for (i = 0; i < numMethods; i++) - _mixer->SetCoderInfo(i, NULL, NULL); + _mixer->SetCoderInfo(i, NULL, NULL, false); /* inStreamSize can be used by BCJ2 to set optimal range of conversion. @@ -346,15 +367,19 @@ HRESULT CEncoder::Encode( */ + /* CSequentialInStreamSizeCount2 *inStreamSizeCountSpec = new CSequentialInStreamSizeCount2; CMyComPtr<ISequentialInStream> inStreamSizeCount = inStreamSizeCountSpec; + */ CSequentialOutStreamSizeCount *outStreamSizeCountSpec = NULL; CMyComPtr<ISequentialOutStream> outStreamSizeCount; - inStreamSizeCountSpec->Init(inStream); + // inStreamSizeCountSpec->Init(inStream); + + // ISequentialInStream *inStreamPointer = inStreamSizeCount; + ISequentialInStream *inStreamPointer = inStream; - ISequentialInStream *inStreamPointer = inStreamSizeCount; CRecordVector<ISequentialOutStream *> outStreamPointers; SetFolder(folderItem); @@ -362,38 +387,66 @@ HRESULT CEncoder::Encode( for (i = 0; i < numMethods; i++) { IUnknown *coder = _mixer->GetCoder(i).GetUnknown(); + /* + { + CEncoder *sfEncoder = NULL; + Z7_DECL_CMyComPtr_QI_FROM( + IGetSfEncoderInternal, + sf, coder) + if (sf) + { + RINOK(sf->GetSfEncoder(&sfEncoder)); + if (!sfEncoder) + return E_FAIL; - CMyComPtr<ICryptoResetInitVector> resetInitVector; - coder->QueryInterface(IID_ICryptoResetInitVector, (void **)&resetInitVector); - if (resetInitVector) + } + } + */ + /* + #ifdef Z7_EXTERNAL_CODECS { - resetInitVector->ResetInitVector(); + Z7_DECL_CMyComPtr_QI_FROM( + ISetCompressCodecsInfo, + setCompressCodecsInfo, coder) + if (setCompressCodecsInfo) + { + // we must use g_ExternalCodecs also + RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(_externalCodecs->GetCodecs)) + } } - - CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties; - coder->QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties); - - CByteBuffer &props = folderItem.Coders[numMethods - 1 - i].Props; - - if (writeCoderProperties) + #endif + */ { - CDynBufSeqOutStream *outStreamSpec = new CDynBufSeqOutStream; - CMyComPtr<ISequentialOutStream> dynOutStream(outStreamSpec); - outStreamSpec->Init(); - writeCoderProperties->WriteCoderProperties(dynOutStream); - outStreamSpec->CopyToBuffer(props); + Z7_DECL_CMyComPtr_QI_FROM( + ICryptoResetInitVector, + resetInitVector, coder) + if (resetInitVector) + { + RINOK(resetInitVector->ResetInitVector()) + } } - else - props.Free(); + { + Z7_DECL_CMyComPtr_QI_FROM( + ICompressSetCoderPropertiesOpt, + optProps, coder) + if (optProps) + { + const PROPID propID = NCoderPropID::kExpectedDataSize; + NWindows::NCOM::CPropVariant prop = (UInt64)expectedDataSize; + RINOK(optProps->SetCoderPropertiesOpt(&propID, &prop, 1)) + } + } + // we must write properties from coder after ResetInitVector() + RINOK(FillProps_from_Coder(coder, folderItem.Coders[numMethods - 1 - i].Props)) } _mixer->SelectMainCoder(false); - UInt32 mainCoder = _mixer->MainCoderIndex; + const UInt32 mainCoder = _mixer->MainCoderIndex; bool useMtProgress = false; if (!_mixer->Is_PackSize_Correct_for_Coder(mainCoder)) { - #ifdef _7ZIP_ST + #ifdef Z7_ST if (!_mixer->IsThere_ExternalCoder_in_PackTree(mainCoder)) #endif useMtProgress = true; @@ -408,11 +461,11 @@ HRESULT CEncoder::Encode( mtOutStreamNotifySpec = new CSequentialOutMtNotify; mtOutStreamNotify = mtOutStreamNotifySpec; mtOutStreamNotifySpec->_stream = outStream; - mtOutStreamNotifySpec->_mtProgresSpec = mtProgressSpec; + mtOutStreamNotifySpec->_mtProgressSpec = mtProgressSpec; - FOR_VECTOR(t, tempBufferSpecs) + FOR_VECTOR (t, tempBufferSpecs) { - tempBufferSpecs[t]->_mtProgresSpec = mtProgressSpec; + tempBufferSpecs[t]->_mtProgressSpec = mtProgressSpec; } } @@ -429,38 +482,54 @@ HRESULT CEncoder::Encode( for (i = 1; i < _bindInfo.PackStreams.Size(); i++) outStreamPointers.Add(tempBuffers[i - 1]); + bool dataAfterEnd_Error; + RINOK(_mixer->Code( &inStreamPointer, &outStreamPointers.Front(), - mtProgress ? (ICompressProgressInfo *)mtProgress : compressProgress)); + mtProgress ? (ICompressProgressInfo *)mtProgress : compressProgress, dataAfterEnd_Error)) if (_bindInfo.PackStreams.Size() != 0) packSizes.Add(outStreamSizeCountSpec->GetSize()); for (i = 1; i < _bindInfo.PackStreams.Size(); i++) { - CInOutTempBuffer &inOutTempBuffer = inOutTempBuffers[i - 1]; - RINOK(inOutTempBuffer.WriteToStream(outStream)); - packSizes.Add(inOutTempBuffer.GetDataSize()); + CInOutTempBuffer &iotb = tempBufferSpecs[i - 1]->TempBuffer; + RINOK(iotb.WriteToStream(outStream)) + packSizes.Add(iotb.GetDataSize()); } - unpackSize = 0; - - for (i = 0; i < _bindInfo.Coders.Size(); i++) + /* Code() in some future codec can change properties. + v23: so we fill properties again after Code() */ + for (i = 0; i < numMethods; i++) + { + IUnknown *coder = _mixer->GetCoder(i).GetUnknown(); + RINOK(FillProps_from_Coder(coder, folderItem.Coders[numMethods - 1 - i].Props)) + } + + return S_OK; +} + + +void CEncoder::Encode_Post( + UInt64 unpackSize, + CRecordVector<UInt64> &coderUnpackSizes) +{ + // unpackSize = 0; + for (unsigned i = 0; i < _bindInfo.Coders.Size(); i++) { - int bond = _bindInfo.FindBond_for_UnpackStream(_DestOut_to_SrcIn[i]); + const int bond = _bindInfo.FindBond_for_UnpackStream(DestOut_to_SrcIn[i]); UInt64 streamSize; if (bond < 0) { - streamSize = inStreamSizeCountSpec->GetSize(); - unpackSize = streamSize; + // streamSize = inStreamSizeCountSpec->GetSize(); + // unpackSize = streamSize; + streamSize = unpackSize; } else - streamSize = _mixer->GetBondStreamSize(bond); + streamSize = _mixer->GetBondStreamSize((unsigned)bond); coderUnpackSizes.Add(streamSize); } - - return S_OK; } @@ -583,17 +652,17 @@ HRESULT CEncoder::EncoderConstr() if (_bindInfo.Coders[ci].NumStreams == 0) break; - UInt32 outIndex = _bindInfo.Coder_to_Stream[ci]; - int bond = _bindInfo.FindBond_for_PackStream(outIndex); + const UInt32 outIndex = _bindInfo.Coder_to_Stream[ci]; + const int bond = _bindInfo.FindBond_for_PackStream(outIndex); if (bond >= 0) { - ci = _bindInfo.Bonds[bond].UnpackIndex; + ci = _bindInfo.Bonds[(unsigned)bond].UnpackIndex; continue; } - int si = _bindInfo.FindStream_in_PackStreams(outIndex); + const int si = _bindInfo.FindStream_in_PackStreams(outIndex); if (si >= 0) - _bindInfo.PackStreams.MoveToFront(si); + _bindInfo.PackStreams.MoveToFront((unsigned)si); break; } } diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zEncode.h b/3rdparty/lzma/CPP/7zip/Archive/7z/7zEncode.h index f1a9b5ad720..849ac63b9f4 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zEncode.h +++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zEncode.h @@ -1,7 +1,7 @@ // 7zEncode.h -#ifndef __7Z_ENCODE_H -#define __7Z_ENCODE_H +#ifndef ZIP7_INC_7Z_ENCODE_H +#define ZIP7_INC_7Z_ENCODE_H #include "7zCompressionMode.h" @@ -12,12 +12,12 @@ namespace NArchive { namespace N7z { -class CMtEncMultiProgress: - public ICompressProgressInfo, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_1( + CMtEncMultiProgress, + ICompressProgressInfo +) CMyComPtr<ICompressProgressInfo> _progress; - #ifndef _7ZIP_ST + #ifndef Z7_ST NWindows::NSynchronization::CCriticalSection CriticalSection; #endif @@ -30,18 +30,15 @@ public: void AddOutSize(UInt64 addOutSize) { - #ifndef _7ZIP_ST + #ifndef Z7_ST NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection); #endif OutSize += addOutSize; } - - MY_UNKNOWN_IMP1(ICompressProgressInfo) - - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); }; -class CEncoder + +class CEncoder Z7_final MY_UNCOPYABLE { #ifdef USE_MIXER_ST NCoderMixer2::CMixerST *_mixerST; @@ -57,10 +54,10 @@ class CEncoder NCoderMixer2::CBindInfo _bindInfo; CRecordVector<CMethodId> _decompressionMethods; - CRecordVector<UInt32> _SrcIn_to_DestOut; - CRecordVector<UInt32> _SrcOut_to_DestIn; - // CRecordVector<UInt32> _DestIn_to_SrcOut; - CRecordVector<UInt32> _DestOut_to_SrcIn; + CRecordVector<UInt32> SrcIn_to_DestOut; + CRecordVector<UInt32> SrcOut_to_DestIn; + // CRecordVector<UInt32> DestIn_to_SrcOut; + CRecordVector<UInt32> DestOut_to_SrcIn; void InitBindConv(); void SetFolder(CFolder &folder); @@ -74,17 +71,23 @@ public: CEncoder(const CCompressionMethodMode &options); ~CEncoder(); HRESULT EncoderConstr(); - HRESULT Encode( + HRESULT Encode1( DECL_EXTERNAL_CODECS_LOC_VARS ISequentialInStream *inStream, // const UInt64 *inStreamSize, const UInt64 *inSizeForReduce, + UInt64 expectedDataSize, CFolder &folderItem, - CRecordVector<UInt64> &coderUnpackSizes, - UInt64 &unpackSize, + // CRecordVector<UInt64> &coderUnpackSizes, + // UInt64 &unpackSize, ISequentialOutStream *outStream, CRecordVector<UInt64> &packSizes, ICompressProgressInfo *compressProgress); + + void Encode_Post( + UInt64 unpackSize, + CRecordVector<UInt64> &coderUnpackSizes); + }; }} diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zExtract.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zExtract.cpp index 05fd80de3fd..5498c590cee 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zExtract.cpp +++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zExtract.cpp @@ -16,10 +16,11 @@ namespace NArchive { namespace N7z { -class CFolderOutStream: - public ISequentialOutStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_1( + CFolderOutStream + , ISequentialOutStream + /* , ICompressGetSubStreamSize */ +) CMyComPtr<ISequentialOutStream> _stream; public: bool TestMode; @@ -31,6 +32,7 @@ private: UInt64 _rem; const UInt32 *_indexes; + // unsigned _startIndex; unsigned _numFiles; unsigned _fileIndex; @@ -40,8 +42,6 @@ private: HRESULT ProcessEmptyFiles(); public: - MY_UNKNOWN_IMP1(ISequentialOutStream) - const CDbEx *_db; CMyComPtr<IArchiveExtractCallback> ExtractCallback; @@ -52,8 +52,6 @@ public: CheckCrc(true) {} - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - HRESULT Init(unsigned startIndex, const UInt32 *indexes, unsigned numFiles); HRESULT FlushCorrupted(Int32 callbackOperationResult); @@ -63,6 +61,7 @@ public: HRESULT CFolderOutStream::Init(unsigned startIndex, const UInt32 *indexes, unsigned numFiles) { + // _startIndex = startIndex; _fileIndex = startIndex; _indexes = indexes; _numFiles = numFiles; @@ -76,11 +75,10 @@ HRESULT CFolderOutStream::Init(unsigned startIndex, const UInt32 *indexes, unsig HRESULT CFolderOutStream::OpenFile(bool isCorrupted) { const CFileItem &fi = _db->Files[_fileIndex]; - UInt32 nextFileIndex = (_indexes ? *_indexes : _fileIndex); - Int32 askMode = (_fileIndex == nextFileIndex) ? - (TestMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract) : + const UInt32 nextFileIndex = (_indexes ? *_indexes : _fileIndex); + Int32 askMode = (_fileIndex == nextFileIndex) ? TestMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract : NExtract::NAskMode::kSkip; if (isCorrupted @@ -90,7 +88,7 @@ HRESULT CFolderOutStream::OpenFile(bool isCorrupted) askMode = NExtract::NAskMode::kTest; CMyComPtr<ISequentialOutStream> realOutStream; - RINOK(ExtractCallback->GetStream(_fileIndex, &realOutStream, askMode)); + RINOK(ExtractCallback->GetStream(_fileIndex, &realOutStream, askMode)) _stream = realOutStream; _crc = CRC_INIT_VAL; @@ -136,13 +134,13 @@ HRESULT CFolderOutStream::ProcessEmptyFiles() { while (_numFiles != 0 && _db->Files[_fileIndex].Size == 0) { - RINOK(OpenFile()); - RINOK(CloseFile()); + RINOK(OpenFile()) + RINOK(CloseFile()) } return S_OK; } -STDMETHODIMP CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -152,6 +150,12 @@ STDMETHODIMP CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *proc if (_fileIsOpen) { UInt32 cur = (size < _rem ? size : (UInt32)_rem); + if (_calcCrc) + { + const UInt32 k_Step = (UInt32)1 << 20; + if (cur > k_Step) + cur = k_Step; + } HRESULT result = S_OK; if (_stream) result = _stream->Write(data, cur, &cur); @@ -164,16 +168,16 @@ STDMETHODIMP CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *proc _rem -= cur; if (_rem == 0) { - RINOK(CloseFile()); - RINOK(ProcessEmptyFiles()); + RINOK(CloseFile()) + RINOK(ProcessEmptyFiles()) } - RINOK(result); + RINOK(result) if (cur == 0) break; continue; } - RINOK(ProcessEmptyFiles()); + RINOK(ProcessEmptyFiles()) if (_numFiles == 0) { // we support partial extracting @@ -186,7 +190,7 @@ STDMETHODIMP CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *proc // return S_FALSE; return k_My_HRESULT_WritingWasCut; } - RINOK(OpenFile()); + RINOK(OpenFile()) } return S_OK; @@ -198,19 +202,37 @@ HRESULT CFolderOutStream::FlushCorrupted(Int32 callbackOperationResult) { if (_fileIsOpen) { - RINOK(CloseFile_and_SetResult(callbackOperationResult)); + RINOK(CloseFile_and_SetResult(callbackOperationResult)) } else { - RINOK(OpenFile(true)); + RINOK(OpenFile(true)) } } return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testModeSpec, IArchiveExtractCallback *extractCallbackSpec) +/* +Z7_COM7F_IMF(CFolderOutStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)) +{ + *value = 0; + // const unsigned numFiles_Original = _numFiles + _fileIndex - _startIndex; + const unsigned numFiles_Original = _numFiles; + if (subStream >= numFiles_Original) + return S_FALSE; // E_FAIL; + *value = _db->Files[_startIndex + (unsigned)subStream].Size; + return S_OK; +} +*/ + + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testModeSpec, IArchiveExtractCallback *extractCallbackSpec)) { + // for GCC + // CFolderOutStream *folderOutStream = new CFolderOutStream; + // CMyComPtr<ISequentialOutStream> outStream(folderOutStream); + COM_TRY_BEGIN CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec; @@ -219,7 +241,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, // numItems = (UInt32)(Int32)-1; - bool allFilesMode = (numItems == (UInt32)(Int32)-1); + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); if (allFilesMode) numItems = _db.Files.Size(); @@ -234,8 +256,8 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, for (i = 0; i < numItems; i++) { - UInt32 fileIndex = allFilesMode ? i : indices[i]; - CNum folderIndex = _db.FileIndexToFolderIndexMap[fileIndex]; + const UInt32 fileIndex = allFilesMode ? i : indices[i]; + const CNum folderIndex = _db.FileIndexToFolderIndexMap[fileIndex]; if (folderIndex == kNumNoIndex) continue; if (folderIndex != prevFolder || fileIndex < nextFile) @@ -247,7 +269,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, } } - RINOK(extractCallback->SetTotal(importantTotalUnpacked)); + RINOK(extractCallback->SetTotal(importantTotalUnpacked)) CLocalProgress *lps = new CLocalProgress; CMyComPtr<ICompressProgressInfo> progress = lps; @@ -258,8 +280,8 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, false #elif !defined(USE_MIXER_ST) true - #elif !defined(__7Z_SET_PROPERTIES) - #ifdef _7ZIP_ST + #elif !defined(Z7_7Z_SET_PROPERTIES) + #ifdef Z7_ST false #else true @@ -271,8 +293,8 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, UInt64 curPacked, curUnpacked; - CMyComPtr<IArchiveExtractCallbackMessage> callbackMessage; - extractCallback.QueryInterface(IID_IArchiveExtractCallbackMessage, &callbackMessage); + CMyComPtr<IArchiveExtractCallbackMessage2> callbackMessage; + extractCallback.QueryInterface(IID_IArchiveExtractCallbackMessage2, &callbackMessage); CFolderOutStream *folderOutStream = new CFolderOutStream; CMyComPtr<ISequentialOutStream> outStream(folderOutStream); @@ -284,7 +306,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, for (UInt32 i = 0;; lps->OutSize += curUnpacked, lps->InSize += curPacked) { - RINOK(lps->SetCur()); + RINOK(lps->SetCur()) if (i >= numItems) break; @@ -293,7 +315,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, curPacked = 0; UInt32 fileIndex = allFilesMode ? i : indices[i]; - CNum folderIndex = _db.FileIndexToFolderIndexMap[fileIndex]; + const CNum folderIndex = _db.FileIndexToFolderIndexMap[fileIndex]; UInt32 numSolidFiles = 1; @@ -306,7 +328,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, for (k = i + 1; k < numItems; k++) { - UInt32 fileIndex2 = allFilesMode ? k : indices[k]; + const UInt32 fileIndex2 = allFilesMode ? k : indices[k]; if (_db.FileIndexToFolderIndexMap[fileIndex2] != folderIndex || fileIndex2 < nextFile) break; @@ -320,20 +342,26 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, } { - HRESULT result = folderOutStream->Init(fileIndex, + const HRESULT result = folderOutStream->Init(fileIndex, allFilesMode ? NULL : indices + i, numSolidFiles); i += numSolidFiles; - RINOK(result); + RINOK(result) } - // to test solid block with zero unpacked size we disable that code if (folderOutStream->WasWritingFinished()) + { + // for debug: to test zero size stream unpacking + // if (folderIndex == kNumNoIndex) // enable this check for debug continue; + } + + if (folderIndex == kNumNoIndex) + return E_FAIL; - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO CMyComPtr<ICryptoGetTextPassword> getTextPassword; if (extractCallback) extractCallback.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword); @@ -341,14 +369,15 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, try { - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO bool isEncrypted = false; bool passwordIsDefined = false; - UString password; + UString_Wipe password; #endif + bool dataAfterEnd_Error = false; - HRESULT result = decoder.Decode( + const HRESULT result = decoder.Decode( EXTERNAL_CODECS_VARS _inStream, _db.ArcInfo.DataStartPosition, @@ -358,29 +387,36 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, outStream, progress, NULL // *inStreamMainRes + , dataAfterEnd_Error - _7Z_DECODER_CRYPRO_VARS - #if !defined(_7ZIP_ST) && !defined(_SFX) - , true, _numThreads + Z7_7Z_DECODER_CRYPRO_VARS + #if !defined(Z7_ST) + , true, _numThreads, _memUsage_Decompress #endif ); - if (result == S_FALSE || result == E_NOTIMPL) + if (result == S_FALSE || result == E_NOTIMPL || dataAfterEnd_Error) { - bool wasFinished = folderOutStream->WasWritingFinished(); - - int resOp = (result == S_FALSE ? - NExtract::NOperationResult::kDataError : - NExtract::NOperationResult::kUnsupportedMethod); + const bool wasFinished = folderOutStream->WasWritingFinished(); - RINOK(folderOutStream->FlushCorrupted(resOp)); + int resOp = NExtract::NOperationResult::kDataError; + + if (result != S_FALSE) + { + if (result == E_NOTIMPL) + resOp = NExtract::NOperationResult::kUnsupportedMethod; + else if (wasFinished && dataAfterEnd_Error) + resOp = NExtract::NOperationResult::kDataAfterEnd; + } + + RINOK(folderOutStream->FlushCorrupted(resOp)) if (wasFinished) { // we don't show error, if it's after required files if (/* !folderOutStream->ExtraWriteWasCut && */ callbackMessage) { - RINOK(callbackMessage->ReportExtractResult(NEventIndexType::kBlockIndex, folderIndex, resOp)); + RINOK(callbackMessage->ReportExtractResult(NEventIndexType::kBlockIndex, folderIndex, resOp)) } } continue; @@ -389,14 +425,15 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, if (result != S_OK) return result; - RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError)); + RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError)) continue; } catch(...) { - RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError)); + RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError)) // continue; - return E_FAIL; + // return E_FAIL; + throw; } } diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zFolderInStream.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zFolderInStream.cpp index 14cdc436452..08231893905 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zFolderInStream.cpp +++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zFolderInStream.cpp @@ -2,6 +2,8 @@ #include "StdAfx.h" +#include "../../../Windows/TimeUtils.h" + #include "7zFolderInStream.h" namespace NArchive { @@ -13,66 +15,129 @@ void CFolderInStream::Init(IArchiveUpdateCallback *updateCallback, _updateCallback = updateCallback; _indexes = indexes; _numFiles = numFiles; - _index = 0; + + _totalSize_for_Coder = 0; + ClearFileInfo(); Processed.ClearAndReserve(numFiles); - CRCs.ClearAndReserve(numFiles); Sizes.ClearAndReserve(numFiles); - - _pos = 0; - _crc = CRC_INIT_VAL; - _size_Defined = false; - _size = 0; + CRCs.ClearAndReserve(numFiles); + TimesDefined.ClearAndReserve(numFiles); + MTimes.ClearAndReserve(Need_MTime ? numFiles : (unsigned)0); + CTimes.ClearAndReserve(Need_CTime ? numFiles : (unsigned)0); + ATimes.ClearAndReserve(Need_ATime ? numFiles : (unsigned)0); + Attribs.ClearAndReserve(Need_Attrib ? numFiles : (unsigned)0); + // FolderCrc = CRC_INIT_VAL; _stream.Release(); } -HRESULT CFolderInStream::OpenStream() +void CFolderInStream::ClearFileInfo() { _pos = 0; _crc = CRC_INIT_VAL; _size_Defined = false; + _times_Defined = false; _size = 0; + FILETIME_Clear(_mTime); + FILETIME_Clear(_cTime); + FILETIME_Clear(_aTime); + _attrib = 0; +} - while (_index < _numFiles) +HRESULT CFolderInStream::OpenStream() +{ + while (Processed.Size() < _numFiles) { CMyComPtr<ISequentialInStream> stream; - HRESULT result = _updateCallback->GetStream(_indexes[_index], &stream); - if (result != S_OK) - { - if (result != S_FALSE) - return result; - } + const HRESULT result = _updateCallback->GetStream(_indexes[Processed.Size()], &stream); + if (result != S_OK && result != S_FALSE) + return result; _stream = stream; if (stream) { - CMyComPtr<IStreamGetSize> streamGetSize; - stream.QueryInterface(IID_IStreamGetSize, &streamGetSize); - if (streamGetSize) { - if (streamGetSize->GetSize(&_size) == S_OK) - _size_Defined = true; + CMyComPtr<IStreamGetProps> getProps; + stream.QueryInterface(IID_IStreamGetProps, (void **)&getProps); + if (getProps) + { + // access could be changed in first myx pass + if (getProps->GetProps(&_size, + Need_CTime ? &_cTime : NULL, + Need_ATime ? &_aTime : NULL, + Need_MTime ? &_mTime : NULL, + Need_Attrib ? &_attrib : NULL) + == S_OK) + { + _size_Defined = true; + _times_Defined = true; + } + return S_OK; + } + } + { + CMyComPtr<IStreamGetSize> streamGetSize; + stream.QueryInterface(IID_IStreamGetSize, &streamGetSize); + if (streamGetSize) + { + if (streamGetSize->GetSize(&_size) == S_OK) + _size_Defined = true; + } + return S_OK; } - return S_OK; } - _index++; - RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); - AddFileInfo(result == S_OK); + RINOK(AddFileInfo(result == S_OK)) } return S_OK; } -void CFolderInStream::AddFileInfo(bool isProcessed) +static void AddFt(CRecordVector<UInt64> &vec, const FILETIME &ft) { - Processed.Add(isProcessed); - Sizes.Add(_pos); - CRCs.Add(CRC_GET_DIGEST(_crc)); + vec.AddInReserved(FILETIME_To_UInt64(ft)); } -STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +/* +HRESULT ReportItemProps(IArchiveUpdateCallbackArcProp *reportArcProp, + UInt32 index, UInt64 size, const UInt32 *crc) +{ + PROPVARIANT prop; + prop.vt = VT_EMPTY; + prop.wReserved1 = 0; + + NWindows::NCOM::PropVarEm_Set_UInt64(&prop, size); + RINOK(reportArcProp->ReportProp(NEventIndexType::kOutArcIndex, index, kpidSize, &prop)); + if (crc) + { + NWindows::NCOM::PropVarEm_Set_UInt32(&prop, *crc); + RINOK(reportArcProp->ReportProp(NEventIndexType::kOutArcIndex, index, kpidCRC, &prop)); + } + return reportArcProp->ReportFinished(NEventIndexType::kOutArcIndex, index, NUpdate::NOperationResult::kOK); +} +*/ + +HRESULT CFolderInStream::AddFileInfo(bool isProcessed) +{ + // const UInt32 index = _indexes[Processed.Size()]; + Processed.AddInReserved(isProcessed); + Sizes.AddInReserved(_pos); + CRCs.AddInReserved(CRC_GET_DIGEST(_crc)); + if (Need_Attrib) Attribs.AddInReserved(_attrib); + TimesDefined.AddInReserved(_times_Defined); + if (Need_MTime) AddFt(MTimes, _mTime); + if (Need_CTime) AddFt(CTimes, _cTime); + if (Need_ATime) AddFt(ATimes, _aTime); + ClearFileInfo(); + /* + if (isProcessed && _reportArcProp) + RINOK(ReportItemProps(_reportArcProp, index, _pos, &crc)) + */ + return _updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK); +} + +Z7_COM7F_IMF(CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -80,43 +145,65 @@ STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSiz { if (_stream) { - UInt32 processed2; - RINOK(_stream->Read(data, size, &processed2)); - if (processed2 != 0) + /* + if (_pos == 0) + { + const UInt32 align = (UInt32)1 << AlignLog; + const UInt32 offset = (UInt32)_totalSize_for_Coder & (align - 1); + if (offset != 0) + { + UInt32 cur = align - offset; + if (cur > size) + cur = size; + memset(data, 0, cur); + data = (Byte *)data + cur; + size -= cur; + // _pos += cur; // for debug + _totalSize_for_Coder += cur; + if (processedSize) + *processedSize += cur; + continue; + } + } + */ + UInt32 cur = size; + const UInt32 kMax = (UInt32)1 << 20; + if (cur > kMax) + cur = kMax; + RINOK(_stream->Read(data, cur, &cur)) + if (cur != 0) { - _crc = CrcUpdate(_crc, data, processed2); - _pos += processed2; + // if (Need_Crc) + _crc = CrcUpdate(_crc, data, cur); + /* + if (FolderCrc) + FolderCrc = CrcUpdate(FolderCrc, data, cur); + */ + _pos += cur; + _totalSize_for_Coder += cur; if (processedSize) - *processedSize = processed2; + *processedSize = cur; // use +=cur, if continue is possible in loop return S_OK; } _stream.Release(); - _index++; - AddFileInfo(true); - - _pos = 0; - _crc = CRC_INIT_VAL; - _size_Defined = false; - _size = 0; - - RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); + RINOK(AddFileInfo(true)) } - if (_index >= _numFiles) + if (Processed.Size() >= _numFiles) break; - RINOK(OpenStream()); + RINOK(OpenStream()) } return S_OK; } -STDMETHODIMP CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value) +Z7_COM7F_IMF(CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)) { *value = 0; if (subStream > Sizes.Size()) return S_FALSE; // E_FAIL; - unsigned index = (unsigned)subStream; + const unsigned index = (unsigned)subStream; if (index < Sizes.Size()) { *value = Sizes[index]; @@ -133,4 +220,45 @@ STDMETHODIMP CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value) return S_OK; } + +/* +HRESULT CFolderInStream::CloseCrcStream() +{ + if (!_crcStream) + return S_OK; + if (!_crcStream_Spec->WasFinished()) + return E_FAIL; + _crc = _crcStream_Spec->GetCRC() ^ CRC_INIT_VAL; // change it + const UInt64 size = _crcStream_Spec->GetSize(); + _pos = size; + _totalSize_for_Coder += size; + _crcStream.Release(); + // _crcStream->ReleaseStream(); + _stream.Release(); + return AddFileInfo(true); +} + +Z7_COM7F_IMF(CFolderInStream::GetNextInSubStream(UInt64 *streamIndexRes, ISequentialInStream **stream) +{ + RINOK(CloseCrcStream()) + *stream = NULL; + *streamIndexRes = Processed.Size(); + if (Processed.Size() >= _numFiles) + return S_OK; + RINOK(OpenStream()); + if (!_stream) + return S_OK; + if (!_crcStream) + { + _crcStream_Spec = new CSequentialInStreamWithCRC; + _crcStream = _crcStream_Spec; + } + _crcStream_Spec->Init(); + _crcStream_Spec->SetStream(_stream); + *stream = _crcStream; + _crcStream->AddRef(); + return S_OK; +} +*/ + }} diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zFolderInStream.h b/3rdparty/lzma/CPP/7zip/Archive/7z/7zFolderInStream.h index 805db54e9d3..6447b25ca74 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zFolderInStream.h +++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zFolderInStream.h @@ -1,12 +1,13 @@ // 7zFolderInStream.h -#ifndef __7Z_FOLDER_IN_STREAM_H -#define __7Z_FOLDER_IN_STREAM_H +#ifndef ZIP7_INC_7Z_FOLDER_IN_STREAM_H +#define ZIP7_INC_7Z_FOLDER_IN_STREAM_H #include "../../../../C/7zCrc.h" #include "../../../Common/MyCom.h" #include "../../../Common/MyVector.h" +// #include "../Common/InStreamWithCRC.h" #include "../../ICoder.h" #include "../IArchive.h" @@ -14,39 +15,67 @@ namespace NArchive { namespace N7z { -class CFolderInStream: - public ISequentialInStream, - public ICompressGetSubStreamSize, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_2( + CFolderInStream + , ISequentialInStream + , ICompressGetSubStreamSize +) + /* + Z7_COM7F_IMP(GetNextStream(UInt64 *streamIndex)) + Z7_IFACE_COM7_IMP(ICompressInSubStreams) + */ + CMyComPtr<ISequentialInStream> _stream; + UInt64 _totalSize_for_Coder; UInt64 _pos; UInt32 _crc; bool _size_Defined; + bool _times_Defined; UInt64 _size; + FILETIME _mTime; + FILETIME _cTime; + FILETIME _aTime; + UInt32 _attrib; - const UInt32 *_indexes; unsigned _numFiles; - unsigned _index; + const UInt32 *_indexes; CMyComPtr<IArchiveUpdateCallback> _updateCallback; + void ClearFileInfo(); HRESULT OpenStream(); - void AddFileInfo(bool isProcessed); - + HRESULT AddFileInfo(bool isProcessed); + // HRESULT CloseCrcStream(); public: + bool Need_MTime; + bool Need_CTime; + bool Need_ATime; + bool Need_Attrib; + // bool Need_Crc; + // bool Need_FolderCrc; + // unsigned AlignLog; + CRecordVector<bool> Processed; - CRecordVector<UInt32> CRCs; CRecordVector<UInt64> Sizes; - - MY_UNKNOWN_IMP2(ISequentialInStream, ICompressGetSubStreamSize) - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value); + CRecordVector<UInt32> CRCs; + CRecordVector<UInt32> Attribs; + CRecordVector<bool> TimesDefined; + CRecordVector<UInt64> MTimes; + CRecordVector<UInt64> CTimes; + CRecordVector<UInt64> ATimes; + // UInt32 FolderCrc; + + // UInt32 GetFolderCrc() const { return CRC_GET_DIGEST(FolderCrc); } + // CSequentialInStreamWithCRC *_crcStream_Spec; + // CMyComPtr<ISequentialInStream> _crcStream; + // CMyComPtr<IArchiveUpdateCallbackArcProp> _reportArcProp; void Init(IArchiveUpdateCallback *updateCallback, const UInt32 *indexes, unsigned numFiles); - bool WasFinished() const { return _index == _numFiles; } + bool WasFinished() const { return Processed.Size() == _numFiles; } + UInt64 Get_TotalSize_for_Coder() const { return _totalSize_for_Coder; } + /* UInt64 GetFullSize() const { UInt64 size = 0; @@ -54,6 +83,17 @@ public: size += Sizes[i]; return size; } + */ + + CFolderInStream(): + Need_MTime(false), + Need_CTime(false), + Need_ATime(false), + Need_Attrib(false) + // , Need_Crc(true) + // , Need_FolderCrc(false) + // , AlignLog(0) + {} }; }} diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandler.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandler.cpp index ccd2c624e66..23d3a9d56a7 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandler.cpp +++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandler.cpp @@ -7,7 +7,7 @@ #include "../../../Common/ComTry.h" #include "../../../Common/IntToString.h" -#ifndef __7Z_SET_PROPERTIES +#ifndef Z7_7Z_SET_PROPERTIES #include "../../../Windows/System.h" #endif @@ -16,8 +16,8 @@ #include "7zHandler.h" #include "7zProperties.h" -#ifdef __7Z_SET_PROPERTIES -#ifdef EXTRACT_ONLY +#ifdef Z7_7Z_SET_PROPERTIES +#ifdef Z7_EXTRACT_ONLY #include "../Common/ParseProperties.h" #endif #endif @@ -30,41 +30,40 @@ namespace N7z { CHandler::CHandler() { - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO _isEncrypted = false; _passwordIsDefined = false; #endif - #ifdef EXTRACT_ONLY + #ifdef Z7_EXTRACT_ONLY _crcSize = 4; - #ifdef __7Z_SET_PROPERTIES - _numThreads = NSystem::GetNumberOfProcessors(); + #ifdef Z7_7Z_SET_PROPERTIES _useMultiThreadMixer = true; #endif #endif } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = _db.Files.Size(); return S_OK; } -#ifdef _SFX +#ifdef Z7_SFX IMP_IInArchive_ArcProps_NO_Table -STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps) +Z7_COM7F_IMF(CHandler::GetNumberOfProperties(UInt32 *numProps)) { *numProps = 0; return S_OK; } -STDMETHODIMP CHandler::GetPropertyInfo(UInt32 /* index */, - BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) +Z7_COM7F_IMF(CHandler::GetPropertyInfo(UInt32 /* index */, + BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)) { return E_NOTIMPL; } @@ -108,34 +107,61 @@ static void ConvertMethodIdToString(AString &res, UInt64 id) res += s + len - ConvertMethodIdToString_Back(s + len, id); } -static unsigned GetStringForSizeValue(char *s, UInt32 val) + +static char *GetStringForSizeValue(char *s, UInt32 val) { - unsigned i; - for (i = 0; i <= 31; i++) + for (unsigned i = 0; i < 32; i++) if (((UInt32)1 << i) == val) { - if (i < 10) + if (i >= 10) { - s[0] = (char)('0' + i); - s[1] = 0; - return 1; + *s++= (char)('0' + i / 10); + i %= 10; } - if (i < 20) { s[0] = '1'; s[1] = (char)('0' + i - 10); } - else if (i < 30) { s[0] = '2'; s[1] = (char)('0' + i - 20); } - else { s[0] = '3'; s[1] = (char)('0' + i - 30); } - s[2] = 0; - return 2; + *s++ = (char)('0' + i); + *s = 0; + return s; } + char c = 'b'; if ((val & ((1 << 20) - 1)) == 0) { val >>= 20; c = 'm'; } else if ((val & ((1 << 10) - 1)) == 0) { val >>= 10; c = 'k'; } - ::ConvertUInt32ToString(val, s); - unsigned pos = MyStringLen(s); - s[pos++] = c; - s[pos] = 0; - return pos; + s = ConvertUInt32ToString(val, s); + *s++ = c; + *s = 0; + return s; } + +static void GetLzma2String(char *s, unsigned d) +{ + if (d > 40) + { + *s = 0; + return; + // s = MyStpCpy(s, "unsup"); + } + else if ((d & 1) == 0) + d = (d >> 1) + 12; + else + { + // s = GetStringForSizeValue(s, (UInt32)3 << ((d >> 1) + 11)); + d = (d >> 1) + 1; + char c = 'k'; + if (d >= 10) + { + c = 'm'; + d -= 10; + } + s = ConvertUInt32ToString((UInt32)3 << d, s); + *s++ = c; + *s = 0; + return; + } + ConvertUInt32ToString(d, s); +} + + /* static inline void AddHexToString(UString &res, Byte value) { @@ -148,8 +174,7 @@ static char *AddProp32(char *s, const char *name, UInt32 v) { *s++ = ':'; s = MyStpCpy(s, name); - ::ConvertUInt32ToString(v, s); - return s + MyStringLen(s); + return ConvertUInt32ToString(v, s); } void CHandler::AddMethodName(AString &s, UInt64 id) @@ -164,15 +189,15 @@ void CHandler::AddMethodName(AString &s, UInt64 id) #endif -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { - #ifndef _SFX + #ifndef Z7_SFX COM_TRY_BEGIN #endif NCOM::CPropVariant prop; switch (propID) { - #ifndef _SFX + #ifndef Z7_SFX case kpidMethod: { AString s; @@ -185,10 +210,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) if (id == k_LZMA2) { s += "LZMA2:"; - if ((pm.Lzma2Prop & 1) == 0) - ConvertUInt32ToString((pm.Lzma2Prop >> 1) + 12, temp); - else - GetStringForSizeValue(temp, 3 << ((pm.Lzma2Prop >> 1) + 11)); + GetLzma2String(temp, pm.Lzma2Prop); s += temp; } else if (id == k_LZMA) @@ -197,6 +219,12 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) GetStringForSizeValue(temp, pm.LzmaDic); s += temp; } + /* + else if (id == k_ZSTD) + { + s += "ZSTD"; + } + */ else AddMethodName(s, id); } @@ -237,36 +265,42 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) prop = v; break; } + + case kpidReadOnly: + { + if (!_db.CanUpdate()) + prop = true; + break; + } } - prop.Detach(value); - return S_OK; - #ifndef _SFX + return prop.Detach(value); + #ifndef Z7_SFX COM_TRY_END #endif } -static void SetFileTimeProp_From_UInt64Def(PROPVARIANT *prop, const CUInt64DefVector &v, int index) +static void SetFileTimeProp_From_UInt64Def(PROPVARIANT *prop, const CUInt64DefVector &v, unsigned index) { UInt64 value; if (v.GetItem(index, value)) - PropVarEm_Set_FileTime64(prop, value); + PropVarEm_Set_FileTime64_Prec(prop, value, k_PropVar_TimePrec_100ns); } bool CHandler::IsFolderEncrypted(CNum folderIndex) const { if (folderIndex == kNumNoIndex) return false; - size_t startPos = _db.FoCodersDataOffset[folderIndex]; + const size_t startPos = _db.FoCodersDataOffset[folderIndex]; const Byte *p = _db.CodersData + startPos; - size_t size = _db.FoCodersDataOffset[folderIndex + 1] - startPos; + const size_t size = _db.FoCodersDataOffset[folderIndex + 1] - startPos; CInByte2 inByte; inByte.Init(p, size); CNum numCoders = inByte.ReadNum(); for (; numCoders != 0; numCoders--) { - Byte mainByte = inByte.ReadByte(); - unsigned idSize = (mainByte & 0xF); + const Byte mainByte = inByte.ReadByte(); + const unsigned idSize = (mainByte & 0xF); const Byte *longID = inByte.GetPtr(); UInt64 id64 = 0; for (unsigned j = 0; j < idSize; j++) @@ -280,20 +314,20 @@ bool CHandler::IsFolderEncrypted(CNum folderIndex) const return false; } -STDMETHODIMP CHandler::GetNumRawProps(UInt32 *numProps) +Z7_COM7F_IMF(CHandler::GetNumRawProps(UInt32 *numProps)) { *numProps = 0; return S_OK; } -STDMETHODIMP CHandler::GetRawPropInfo(UInt32 /* index */, BSTR *name, PROPID *propID) +Z7_COM7F_IMF(CHandler::GetRawPropInfo(UInt32 /* index */, BSTR *name, PROPID *propID)) { *name = NULL; *propID = kpidNtSecure; return S_OK; } -STDMETHODIMP CHandler::GetParent(UInt32 /* index */, UInt32 *parent, UInt32 *parentType) +Z7_COM7F_IMF(CHandler::GetParent(UInt32 /* index */, UInt32 *parent, UInt32 *parentType)) { /* const CFileItem &file = _db.Files[index]; @@ -305,7 +339,7 @@ STDMETHODIMP CHandler::GetParent(UInt32 /* index */, UInt32 *parent, UInt32 *par return S_OK; } -STDMETHODIMP CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) +Z7_COM7F_IMF(CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)) { *data = NULL; *dataSize = 0; @@ -347,7 +381,7 @@ STDMETHODIMP CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data return S_OK; } -#ifndef _SFX +#ifndef Z7_SFX HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const { @@ -360,9 +394,9 @@ HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const unsigned pos = kTempSize; temp[--pos] = 0; - size_t startPos = _db.FoCodersDataOffset[folderIndex]; + const size_t startPos = _db.FoCodersDataOffset[folderIndex]; const Byte *p = _db.CodersData + startPos; - size_t size = _db.FoCodersDataOffset[folderIndex + 1] - startPos; + const size_t size = _db.FoCodersDataOffset[folderIndex + 1] - startPos; CInByte2 inByte; inByte.Init(p, size); @@ -374,10 +408,10 @@ HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const { if (pos < 32) // max size of property break; - Byte mainByte = inByte.ReadByte(); - unsigned idSize = (mainByte & 0xF); - const Byte *longID = inByte.GetPtr(); + const Byte mainByte = inByte.ReadByte(); UInt64 id64 = 0; + const unsigned idSize = (mainByte & 0xF); + const Byte *longID = inByte.GetPtr(); for (unsigned j = 0; j < idSize; j++) id64 = ((id64 << 8) | longID[j]); inByte.SkipDataNoCheck(idSize); @@ -403,21 +437,21 @@ HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const if (id64 <= (UInt32)0xFFFFFFFF) { - UInt32 id = (UInt32)id64; + const UInt32 id = (UInt32)id64; if (id == k_LZMA) { name = "LZMA"; if (propsSize == 5) { - UInt32 dicSize = GetUi32((const Byte *)props + 1); - char *dest = s + GetStringForSizeValue(s, dicSize); + const UInt32 dicSize = GetUi32((const Byte *)props + 1); + char *dest = GetStringForSizeValue(s, dicSize); UInt32 d = props[0]; if (d != 0x5D) { - UInt32 lc = d % 9; + const UInt32 lc = d % 9; d /= 9; - UInt32 pb = d / 5; - UInt32 lp = d % 5; + const UInt32 pb = d / 5; + const UInt32 lp = d % 5; if (lc != 3) dest = AddProp32(dest, "lc", lc); if (lp != 0) dest = AddProp32(dest, "lp", lp); if (pb != 2) dest = AddProp32(dest, "pb", pb); @@ -428,24 +462,16 @@ HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const { name = "LZMA2"; if (propsSize == 1) - { - Byte d = props[0]; - if ((d & 1) == 0) - ConvertUInt32ToString((UInt32)((d >> 1) + 12), s); - else - GetStringForSizeValue(s, 3 << ((d >> 1) + 11)); - } + GetLzma2String(s, props[0]); } else if (id == k_PPMD) { name = "PPMD"; if (propsSize == 5) { - Byte order = *props; char *dest = s; *dest++ = 'o'; - ConvertUInt32ToString(order, dest); - dest += MyStringLen(dest); + dest = ConvertUInt32ToString(*props, dest); dest = MyStpCpy(dest, ":mem"); GetStringForSizeValue(dest, GetUi32(props + 1)); } @@ -456,6 +482,16 @@ HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const if (propsSize == 1) ConvertUInt32ToString((UInt32)props[0] + 1, s); } + else if (id == k_ARM64) + { + name = "ARM64"; + if (propsSize == 4) + ConvertUInt32ToString(GetUi32(props), s); + /* + else if (propsSize != 0) + MyStringCopy(s, "unsupported"); + */ + } else if (id == k_BCJ2) name = "BCJ2"; else if (id == k_BCJ) name = "BCJ"; else if (id == k_AES) @@ -463,8 +499,8 @@ HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const name = "7zAES"; if (propsSize >= 1) { - Byte firstByte = props[0]; - UInt32 numCyclesPower = firstByte & 0x3F; + const Byte firstByte = props[0]; + const UInt32 numCyclesPower = firstByte & 0x3F; ConvertUInt32ToString(numCyclesPower, s); } } @@ -472,8 +508,8 @@ HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const if (name) { - unsigned nameLen = MyStringLen(name); - unsigned propsLen = MyStringLen(s); + const unsigned nameLen = MyStringLen(name); + const unsigned propsLen = MyStringLen(s); unsigned totalLen = nameLen + propsLen; if (propsLen != 0) totalLen++; @@ -502,7 +538,7 @@ HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const pos -= ConvertMethodIdToString_Back(temp + pos, id64); else { - unsigned len = methodName.Len(); + const unsigned len = methodName.Len(); if (len + 5 > pos) break; pos -= len; @@ -526,9 +562,9 @@ HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const #endif -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { - PropVariant_Clear(value); + RINOK(PropVariant_Clear(value)) // COM_TRY_BEGIN // NCOM::CPropVariant prop; @@ -540,7 +576,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val */ const CFileItem &item = _db.Files[index]; - UInt32 index2 = index; + const UInt32 index2 = index; switch (propID) { @@ -555,7 +591,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val { // prop = ref2.PackSize; { - CNum folderIndex = _db.FileIndexToFolderIndexMap[index2]; + const CNum folderIndex = _db.FileIndexToFolderIndexMap[index2]; if (folderIndex != kNumNoIndex) { if (_db.FolderStartFileIndex[folderIndex] == (CNum)index2) @@ -575,7 +611,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val case kpidCTime: SetFileTimeProp_From_UInt64Def(value, _db.CTime, index2); break; case kpidATime: SetFileTimeProp_From_UInt64Def(value, _db.ATime, index2); break; case kpidMTime: SetFileTimeProp_From_UInt64Def(value, _db.MTime, index2); break; - case kpidAttrib: if (item.AttribDefined) PropVarEm_Set_UInt32(value, item.Attrib); break; + case kpidAttrib: if (_db.Attrib.ValidAndDefined(index2)) PropVarEm_Set_UInt32(value, _db.Attrib.Vals[index2]); break; case kpidCRC: if (item.CrcDefined) PropVarEm_Set_UInt32(value, item.Crc); break; case kpidEncrypted: PropVarEm_Set_Bool(value, IsFolderEncrypted(_db.FileIndexToFolderIndexMap[index2])); break; case kpidIsAnti: PropVarEm_Set_Bool(value, _db.IsItemAnti(index2)); break; @@ -596,24 +632,24 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val case kpidPath: return _db.GetPath_Prop(index, value); - #ifndef _SFX + #ifndef Z7_SFX case kpidMethod: return SetMethodToProp(_db.FileIndexToFolderIndexMap[index2], value); case kpidBlock: { - CNum folderIndex = _db.FileIndexToFolderIndexMap[index2]; + const CNum folderIndex = _db.FileIndexToFolderIndexMap[index2]; if (folderIndex != kNumNoIndex) PropVarEm_Set_UInt32(value, (UInt32)folderIndex); } break; - /* + #ifdef Z7_7Z_SHOW_PACK_STREAMS_SIZES case kpidPackedSize0: case kpidPackedSize1: case kpidPackedSize2: case kpidPackedSize3: case kpidPackedSize4: { - CNum folderIndex = _db.FileIndexToFolderIndexMap[index2]; + const CNum folderIndex = _db.FileIndexToFolderIndexMap[index2]; if (folderIndex != kNumNoIndex) { if (_db.FolderStartFileIndex[folderIndex] == (CNum)index2 && @@ -627,22 +663,22 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val PropVarEm_Set_UInt64(value, 0); } break; - */ + #endif #endif } - // prop.Detach(value); + // return prop.Detach(value); return S_OK; // COM_TRY_END } -STDMETHODIMP CHandler::Open(IInStream *stream, +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *maxCheckStartPosition, - IArchiveOpenCallback *openArchiveCallback) + IArchiveOpenCallback *openArchiveCallback)) { COM_TRY_BEGIN Close(); - #ifndef _SFX + #ifndef Z7_SFX _fileInfoPopIDs.Clear(); #endif @@ -650,31 +686,31 @@ STDMETHODIMP CHandler::Open(IInStream *stream, { CMyComPtr<IArchiveOpenCallback> openArchiveCallbackTemp = openArchiveCallback; - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO CMyComPtr<ICryptoGetTextPassword> getTextPassword; if (openArchiveCallback) openArchiveCallbackTemp.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword); #endif CInArchive archive( - #ifdef __7Z_SET_PROPERTIES + #ifdef Z7_7Z_SET_PROPERTIES _useMultiThreadMixer #else true #endif ); _db.IsArc = false; - RINOK(archive.Open(stream, maxCheckStartPosition)); + RINOK(archive.Open(stream, maxCheckStartPosition)) _db.IsArc = true; HRESULT result = archive.ReadDatabase( EXTERNAL_CODECS_VARS _db - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO , getTextPassword, _isEncrypted, _passwordIsDefined, _password #endif ); - RINOK(result); + RINOK(result) _inStream = stream; } @@ -687,35 +723,35 @@ STDMETHODIMP CHandler::Open(IInStream *stream, return E_OUTOFMEMORY; } // _inStream = stream; - #ifndef _SFX + #ifndef Z7_SFX FillPopIDs(); #endif return S_OK; COM_TRY_END } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { COM_TRY_BEGIN _inStream.Release(); _db.Clear(); - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO _isEncrypted = false; _passwordIsDefined = false; - _password.Empty(); + _password.Wipe_and_Empty(); #endif return S_OK; COM_TRY_END } -#ifdef __7Z_SET_PROPERTIES -#ifdef EXTRACT_ONLY +#ifdef Z7_7Z_SET_PROPERTIES +#ifdef Z7_EXTRACT_ONLY -STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps) +Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)) { COM_TRY_BEGIN - const UInt32 numProcessors = NSystem::GetNumberOfProcessors(); - _numThreads = numProcessors; + + InitCommon(); _useMultiThreadMixer = true; for (UInt32 i = 0; i < numProps; i++) @@ -726,21 +762,23 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR return E_INVALIDARG; const PROPVARIANT &value = values[i]; UInt32 number; - unsigned index = ParseStringToUInt32(name, number); + const unsigned index = ParseStringToUInt32(name, number); if (index == 0) { if (name.IsEqualTo("mtf")) { - RINOK(PROPVARIANT_to_bool(value, _useMultiThreadMixer)); + RINOK(PROPVARIANT_to_bool(value, _useMultiThreadMixer)) continue; } - if (name.IsPrefixedBy_Ascii_NoCase("mt")) { - RINOK(ParseMtProp(name.Ptr(2), value, numProcessors, _numThreads)); - continue; + HRESULT hres; + if (SetCommonProperty(name, value, hres)) + { + RINOK(hres) + continue; + } } - else - return E_INVALIDARG; + return E_INVALIDARG; } } return S_OK; diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandler.h b/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandler.h index d46401afe3c..b1c04669832 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandler.h +++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandler.h @@ -1,45 +1,43 @@ // 7z/Handler.h -#ifndef __7Z_HANDLER_H -#define __7Z_HANDLER_H +#ifndef ZIP7_7Z_HANDLER_H +#define ZIP7_7Z_HANDLER_H #include "../../ICoder.h" #include "../IArchive.h" #include "../../Common/CreateCoder.h" -#ifndef EXTRACT_ONLY -#include "../Common/HandlerOut.h" +#ifndef Z7_7Z_SET_PROPERTIES + +#ifdef Z7_EXTRACT_ONLY + #if !defined(Z7_ST) && !defined(Z7_SFX) + #define Z7_7Z_SET_PROPERTIES + #endif +#else + #define Z7_7Z_SET_PROPERTIES +#endif + #endif +// #ifdef Z7_7Z_SET_PROPERTIES +#include "../Common/HandlerOut.h" +// #endif + #include "7zCompressionMode.h" #include "7zIn.h" namespace NArchive { namespace N7z { -#ifndef __7Z_SET_PROPERTIES - -#ifdef EXTRACT_ONLY - #if !defined(_7ZIP_ST) && !defined(_SFX) - #define __7Z_SET_PROPERTIES - #endif -#else - #define __7Z_SET_PROPERTIES -#endif - -#endif - -#ifndef EXTRACT_ONLY +#ifndef Z7_EXTRACT_ONLY class COutHandler: public CMultiMethodProps { HRESULT SetSolidFromString(const UString &s); HRESULT SetSolidFromPROPVARIANT(const PROPVARIANT &value); public: - bool _removeSfxBlock; - UInt64 _numSolidFiles; UInt64 _numSolidBytes; bool _numSolidBytesDefined; @@ -51,12 +49,14 @@ public: bool _encryptHeaders; // bool _useParents; 9.26 - CBoolPair Write_CTime; - CBoolPair Write_ATime; - CBoolPair Write_MTime; + CHandlerTimeOptions TimeOptions; + + CBoolPair Write_Attrib; bool _useMultiThreadMixer; + bool _removeSfxBlock; + // bool _volumeMode; void InitSolidFiles() { _numSolidFiles = (UInt64)(Int64)(-1); } @@ -69,72 +69,73 @@ public: _numSolidBytesDefined = false; } + void InitProps7z(); void InitProps(); - COutHandler() { InitProps(); } + COutHandler() { InitProps7z(); } HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value); }; #endif -class CHandler: +class CHandler Z7_final: public IInArchive, public IArchiveGetRawProps, - #ifdef __7Z_SET_PROPERTIES + + #ifdef Z7_7Z_SET_PROPERTIES public ISetProperties, #endif - #ifndef EXTRACT_ONLY + + #ifndef Z7_EXTRACT_ONLY public IOutArchive, #endif - PUBLIC_ISetCompressCodecsInfo - public CMyUnknownImp - #ifndef EXTRACT_ONLY - , public COutHandler - #endif -{ -public: - MY_QUERYINTERFACE_BEGIN2(IInArchive) - MY_QUERYINTERFACE_ENTRY(IArchiveGetRawProps) - #ifdef __7Z_SET_PROPERTIES - MY_QUERYINTERFACE_ENTRY(ISetProperties) - #endif - #ifndef EXTRACT_ONLY - MY_QUERYINTERFACE_ENTRY(IOutArchive) - #endif - QUERY_ENTRY_ISetCompressCodecsInfo - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - INTERFACE_IInArchive(;) - INTERFACE_IArchiveGetRawProps(;) - - #ifdef __7Z_SET_PROPERTIES - STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps); - #endif + + Z7_PUBLIC_ISetCompressCodecsInfo_IFEC + + public CMyUnknownImp, - #ifndef EXTRACT_ONLY - INTERFACE_IOutArchive(;) + #ifndef Z7_EXTRACT_ONLY + public COutHandler + #else + public CCommonMethodProps #endif - +{ + Z7_COM_QI_BEGIN2(IInArchive) + Z7_COM_QI_ENTRY(IArchiveGetRawProps) + #ifdef Z7_7Z_SET_PROPERTIES + Z7_COM_QI_ENTRY(ISetProperties) + #endif + #ifndef Z7_EXTRACT_ONLY + Z7_COM_QI_ENTRY(IOutArchive) + #endif + Z7_COM_QI_ENTRY_ISetCompressCodecsInfo_IFEC + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(IInArchive) + Z7_IFACE_COM7_IMP(IArchiveGetRawProps) + #ifdef Z7_7Z_SET_PROPERTIES + Z7_IFACE_COM7_IMP(ISetProperties) + #endif + #ifndef Z7_EXTRACT_ONLY + Z7_IFACE_COM7_IMP(IOutArchive) + #endif DECL_ISetCompressCodecsInfo - CHandler(); - private: CMyComPtr<IInStream> _inStream; NArchive::N7z::CDbEx _db; - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO bool _isEncrypted; bool _passwordIsDefined; - UString _password; - #endif + UString _password; // _Wipe + #endif - #ifdef EXTRACT_ONLY + #ifdef Z7_EXTRACT_ONLY - #ifdef __7Z_SET_PROPERTIES - UInt32 _numThreads; + #ifdef Z7_7Z_SET_PROPERTIES bool _useMultiThreadMixer; #endif @@ -146,17 +147,12 @@ private: HRESULT PropsMethod_To_FullMethod(CMethodFull &dest, const COneMethodInfo &m); HRESULT SetHeaderMethod(CCompressionMethodMode &headerMethod); - HRESULT SetMainMethod(CCompressionMethodMode &method - #ifndef _7ZIP_ST - , UInt32 numThreads - #endif - ); - + HRESULT SetMainMethod(CCompressionMethodMode &method); #endif bool IsFolderEncrypted(CNum folderIndex) const; - #ifndef _SFX + #ifndef Z7_SFX CRecordVector<UInt64> _fileInfoPopIDs; void FillPopIDs(); @@ -166,6 +162,13 @@ private: #endif DECL_EXTERNAL_CODECS_VARS + +public: + CHandler(); + ~CHandler() + { + Close(); + } }; }} diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandlerOut.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandlerOut.cpp index 2b86ed26ab7..ff8735f0f7e 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandlerOut.cpp +++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zHandlerOut.cpp @@ -13,16 +13,19 @@ #include "7zOut.h" #include "7zUpdate.h" +#ifndef Z7_EXTRACT_ONLY + using namespace NWindows; namespace NArchive { namespace N7z { -static const char *k_LZMA_Name = "LZMA"; -static const char *kDefaultMethodName = "LZMA2"; -static const char *k_Copy_Name = "Copy"; +#define k_LZMA_Name "LZMA" +#define kDefaultMethodName "LZMA2" +#define k_Copy_Name "Copy" + +#define k_MatchFinder_ForHeaders "BT2" -static const char *k_MatchFinder_ForHeaders = "BT2"; static const UInt32 k_NumFastBytes_ForHeaders = 273; static const UInt32 k_Level_ForHeaders = 5; static const UInt32 k_Dictionary_ForHeaders = @@ -32,7 +35,7 @@ static const UInt32 k_Dictionary_ForHeaders = 1 << 20; #endif -STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type) +Z7_COM7F_IMF(CHandler::GetFileTimeType(UInt32 *type)) { *type = NFileTimeType::kWindows; return S_OK; @@ -40,9 +43,12 @@ STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type) HRESULT CHandler::PropsMethod_To_FullMethod(CMethodFull &dest, const COneMethodInfo &m) { - if (!FindMethod( + bool isFilter; + dest.CodecIndex = FindMethod_Index( EXTERNAL_CODECS_VARS - m.MethodName, dest.Id, dest.NumStreams)) + m.MethodName, true, + dest.Id, dest.NumStreams, isFilter); + if (dest.CodecIndex < 0) return E_INVALIDARG; (CProps &)dest = (CProps &)m; return S_OK; @@ -64,15 +70,12 @@ HRESULT CHandler::SetHeaderMethod(CCompressionMethodMode &headerMethod) return PropsMethod_To_FullMethod(methodFull, m); } -HRESULT CHandler::SetMainMethod( - CCompressionMethodMode &methodMode - #ifndef _7ZIP_ST - , UInt32 numThreads - #endif - ) + +HRESULT CHandler::SetMainMethod(CCompressionMethodMode &methodMode) { methodMode.Bonds = _bonds; + // we create local copy of _methods. So we can modify it. CObjectVector<COneMethodInfo> methods = _methods; { @@ -106,60 +109,200 @@ HRESULT CHandler::SetMainMethod( } const UInt64 kSolidBytes_Min = (1 << 24); - const UInt64 kSolidBytes_Max = ((UInt64)1 << 32) - 1; + const UInt64 kSolidBytes_Max = ((UInt64)1 << 32); bool needSolid = false; FOR_VECTOR (i, methods) { COneMethodInfo &oneMethodInfo = methods[i]; - SetGlobalLevelAndThreads(oneMethodInfo - #ifndef _7ZIP_ST - , numThreads - #endif - ); + + SetGlobalLevelTo(oneMethodInfo); + + #ifndef Z7_ST + const bool numThreads_WasSpecifiedInMethod = (oneMethodInfo.Get_NumThreads() >= 0); + if (!numThreads_WasSpecifiedInMethod) + { + // here we set the (NCoderPropID::kNumThreads) property in each method, only if there is no such property already + CMultiMethodProps::SetMethodThreadsTo_IfNotFinded(oneMethodInfo, methodMode.NumThreads); + } + #endif CMethodFull &methodFull = methodMode.Methods.AddNew(); - RINOK(PropsMethod_To_FullMethod(methodFull, oneMethodInfo)); + RINOK(PropsMethod_To_FullMethod(methodFull, oneMethodInfo)) + + #ifndef Z7_ST + methodFull.Set_NumThreads = true; + methodFull.NumThreads = methodMode.NumThreads; + #endif if (methodFull.Id != k_Copy) needSolid = true; - if (_numSolidBytesDefined) - continue; - - UInt32 dicSize; + UInt64 dicSize; switch (methodFull.Id) { case k_LZMA: case k_LZMA2: dicSize = oneMethodInfo.Get_Lzma_DicSize(); break; case k_PPMD: dicSize = oneMethodInfo.Get_Ppmd_MemSize(); break; case k_Deflate: dicSize = (UInt32)1 << 15; break; + case k_Deflate64: dicSize = (UInt32)1 << 16; break; case k_BZip2: dicSize = oneMethodInfo.Get_BZip2_BlockSize(); break; + // case k_ZSTD: dicSize = 1 << 23; break; default: continue; } - - _numSolidBytes = (UInt64)dicSize << 7; - if (_numSolidBytes < kSolidBytes_Min) _numSolidBytes = kSolidBytes_Min; - if (_numSolidBytes > kSolidBytes_Max) _numSolidBytes = kSolidBytes_Max; + + UInt64 numSolidBytes; + + /* + if (methodFull.Id == k_ZSTD) + { + // continue; + NCompress::NZstd::CEncoderProps encoderProps; + RINOK(oneMethodInfo.Set_PropsTo_zstd(encoderProps)); + CZstdEncProps &zstdProps = encoderProps.EncProps; + ZstdEncProps_NormalizeFull(&zstdProps); + UInt64 cs = (UInt64)(zstdProps.jobSize); + UInt32 winSize = (UInt32)(1 << zstdProps.windowLog); + if (cs < winSize) + cs = winSize; + numSolidBytes = cs << 6; + const UInt64 kSolidBytes_Zstd_Max = ((UInt64)1 << 34); + if (numSolidBytes > kSolidBytes_Zstd_Max) + numSolidBytes = kSolidBytes_Zstd_Max; + + methodFull.Set_NumThreads = false; // we don't use ICompressSetCoderMt::SetNumberOfThreads() for LZMA2 encoder + + #ifndef Z7_ST + if (!numThreads_WasSpecifiedInMethod + && !methodMode.NumThreads_WasForced + && methodMode.MemoryUsageLimit_WasSet + ) + { + const UInt32 numThreads_Original = methodMode.NumThreads; + const UInt32 numThreads_New = ZstdEncProps_GetNumThreads_for_MemUsageLimit( + &zstdProps, + methodMode.MemoryUsageLimit, + numThreads_Original); + if (numThreads_Original != numThreads_New) + { + CMultiMethodProps::SetMethodThreadsTo_Replace(methodFull, numThreads_New); + } + } + #endif + } + else + */ + if (methodFull.Id == k_LZMA2) + { + // he we calculate default chunk Size for LZMA2 as defined in LZMA2 encoder code + /* lzma2 code use dictionary up to fake 4 GiB to calculate ChunkSize. + So we do same */ + UInt64 cs = (UInt64)dicSize << 2; + const UInt32 kMinSize = (UInt32)1 << 20; + const UInt32 kMaxSize = (UInt32)1 << 28; + if (cs < kMinSize) cs = kMinSize; + if (cs > kMaxSize) cs = kMaxSize; + if (cs < dicSize) cs = dicSize; + cs += (kMinSize - 1); + cs &= ~(UInt64)(kMinSize - 1); + // we want to use at least 64 chunks (threads) per one solid block. + + // here we don't use chunkSize property + numSolidBytes = cs << 6; + + // here we get real chunkSize + cs = oneMethodInfo.Get_Xz_BlockSize(); + if (dicSize > cs) + dicSize = cs; + + const UInt64 kSolidBytes_Lzma2_Max = ((UInt64)1 << 34); + if (numSolidBytes > kSolidBytes_Lzma2_Max) + numSolidBytes = kSolidBytes_Lzma2_Max; + + methodFull.Set_NumThreads = false; // we don't use ICompressSetCoderMt::SetNumberOfThreads() for LZMA2 encoder + + #ifndef Z7_ST + if (!numThreads_WasSpecifiedInMethod + && !methodMode.NumThreads_WasForced + && methodMode.MemoryUsageLimit_WasSet + ) + { + const UInt32 lzmaThreads = oneMethodInfo.Get_Lzma_NumThreads(); + const UInt32 numBlockThreads_Original = methodMode.NumThreads / lzmaThreads; + + if (numBlockThreads_Original > 1) + { + /* + const UInt32 kNumThreads_Max = 1024; + if (numBlockThreads > kNumMaxThreads) + numBlockThreads = kNumMaxThreads; + */ + + UInt32 numBlockThreads = numBlockThreads_Original; + const UInt64 lzmaMemUsage = oneMethodInfo.Get_Lzma_MemUsage(false); // solid + + for (; numBlockThreads > 1; numBlockThreads--) + { + UInt64 size = numBlockThreads * (lzmaMemUsage + cs); + UInt32 numPackChunks = numBlockThreads + (numBlockThreads / 8) + 1; + if (cs < ((UInt32)1 << 26)) numPackChunks++; + if (cs < ((UInt32)1 << 24)) numPackChunks++; + if (cs < ((UInt32)1 << 22)) numPackChunks++; + size += numPackChunks * cs; + // printf("\nnumBlockThreads = %d, size = %d\n", (unsigned)(numBlockThreads), (unsigned)(size >> 20)); + if (size <= methodMode.MemoryUsageLimit) + break; + } + + if (numBlockThreads == 0) + numBlockThreads = 1; + if (numBlockThreads != numBlockThreads_Original) + { + const UInt32 numThreads_New = numBlockThreads * lzmaThreads; + CMultiMethodProps::SetMethodThreadsTo_Replace(methodFull, numThreads_New); + } + } + } + #endif + } + else + { + numSolidBytes = (UInt64)dicSize << 7; + if (numSolidBytes > kSolidBytes_Max) + numSolidBytes = kSolidBytes_Max; + } + + if (_numSolidBytesDefined) + continue; + + if (numSolidBytes < kSolidBytes_Min) + numSolidBytes = kSolidBytes_Min; + _numSolidBytes = numSolidBytes; _numSolidBytesDefined = true; } if (!_numSolidBytesDefined) + { if (needSolid) _numSolidBytes = kSolidBytes_Max; else _numSolidBytes = 0; + } _numSolidBytesDefined = true; + + return S_OK; } -static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, int index, PROPID propID, UInt64 &ft, bool &ftDefined) + + +static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, unsigned index, PROPID propID, UInt64 &ft, bool &ftDefined) { // ft = 0; // ftDefined = false; NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(index, propID, &prop)); + RINOK(updateCallback->GetProperty(index, propID, &prop)) if (prop.vt == VT_FILETIME) { ft = prop.filetime.dwLowDateTime | ((UInt64)prop.filetime.dwHighDateTime << 32); @@ -242,13 +385,13 @@ static int AddFolder(CObjectVector<CTreeFolder> &treeFolders, int cur, const USt } */ -STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, - IArchiveUpdateCallback *updateCallback) +Z7_COM7F_IMF(CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, + IArchiveUpdateCallback *updateCallback)) { COM_TRY_BEGIN - const CDbEx *db = 0; - #ifdef _7Z_VOL + const CDbEx *db = NULL; + #ifdef Z7_7Z_VOL if (_volumes.Size() > 1) return E_FAIL; const CVolume *volume = 0; @@ -258,13 +401,17 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt db = &volume->Database; } #else - if (_inStream != 0) + if (_inStream) db = &_db; #endif + if (db && !db->CanUpdate()) + return E_NOTIMPL; + /* - CMyComPtr<IArchiveGetRawProps> getRawProps; - updateCallback->QueryInterface(IID_IArchiveGetRawProps, (void **)&getRawProps); + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveGetRawProps, + getRawProps, updateCallback) CUniqBlocks secureBlocks; secureBlocks.AddUniq(NULL, 0); @@ -279,18 +426,21 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt CObjectVector<CUpdateItem> updateItems; - bool need_CTime = (Write_CTime.Def && Write_CTime.Val); - bool need_ATime = (Write_ATime.Def && Write_ATime.Val); - bool need_MTime = (Write_MTime.Def && Write_MTime.Val || !Write_MTime.Def); + bool need_CTime = (TimeOptions.Write_CTime.Def && TimeOptions.Write_CTime.Val); + bool need_ATime = (TimeOptions.Write_ATime.Def && TimeOptions.Write_ATime.Val); + bool need_MTime = (TimeOptions.Write_MTime.Def ? TimeOptions.Write_MTime.Val : true); + bool need_Attrib = (Write_Attrib.Def ? Write_Attrib.Val : true); if (db && !db->Files.IsEmpty()) { - if (!Write_CTime.Def) need_CTime = !db->CTime.Defs.IsEmpty(); - if (!Write_ATime.Def) need_ATime = !db->ATime.Defs.IsEmpty(); - if (!Write_MTime.Def) need_MTime = !db->MTime.Defs.IsEmpty(); + if (!TimeOptions.Write_CTime.Def) need_CTime = !db->CTime.Defs.IsEmpty(); + if (!TimeOptions.Write_ATime.Def) need_ATime = !db->ATime.Defs.IsEmpty(); + if (!TimeOptions.Write_MTime.Def) need_MTime = !db->MTime.Defs.IsEmpty(); + if (!Write_Attrib.Def) need_Attrib = !db->Attrib.Defs.IsEmpty(); } - UString s; + // UString s; + UString name; for (UInt32 i = 0; i < numItems; i++) { @@ -298,45 +448,46 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt UInt32 indexInArchive; if (!updateCallback) return E_FAIL; - RINOK(updateCallback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArchive)); + RINOK(updateCallback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArchive)) CUpdateItem ui; ui.NewProps = IntToBool(newProps); ui.NewData = IntToBool(newData); - ui.IndexInArchive = indexInArchive; + ui.IndexInArchive = (int)indexInArchive; ui.IndexInClient = i; ui.IsAnti = false; ui.Size = 0; - UString name; + name.Empty(); // bool isAltStream = false; if (ui.IndexInArchive != -1) { - if (db == 0 || (unsigned)ui.IndexInArchive >= db->Files.Size()) + if (!db || (unsigned)ui.IndexInArchive >= db->Files.Size()) return E_INVALIDARG; - const CFileItem &fi = db->Files[ui.IndexInArchive]; + const CFileItem &fi = db->Files[(unsigned)ui.IndexInArchive]; if (!ui.NewProps) { - _db.GetPath(ui.IndexInArchive, name); + _db.GetPath((unsigned)ui.IndexInArchive, name); } ui.IsDir = fi.IsDir; ui.Size = fi.Size; // isAltStream = fi.IsAltStream; - ui.IsAnti = db->IsItemAnti(ui.IndexInArchive); + ui.IsAnti = db->IsItemAnti((unsigned)ui.IndexInArchive); if (!ui.NewProps) { - ui.CTimeDefined = db->CTime.GetItem(ui.IndexInArchive, ui.CTime); - ui.ATimeDefined = db->ATime.GetItem(ui.IndexInArchive, ui.ATime); - ui.MTimeDefined = db->MTime.GetItem(ui.IndexInArchive, ui.MTime); + ui.CTimeDefined = db->CTime.GetItem((unsigned)ui.IndexInArchive, ui.CTime); + ui.ATimeDefined = db->ATime.GetItem((unsigned)ui.IndexInArchive, ui.ATime); + ui.MTimeDefined = db->MTime.GetItem((unsigned)ui.IndexInArchive, ui.MTime); } } if (ui.NewProps) { bool folderStatusIsDefined; + if (need_Attrib) { NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(i, kpidAttrib, &prop)); + RINOK(updateCallback->GetProperty(i, kpidAttrib, &prop)) if (prop.vt == VT_EMPTY) ui.AttribDefined = false; else if (prop.vt != VT_UI4) @@ -349,9 +500,9 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt } // we need MTime to sort files. - if (need_CTime) RINOK(GetTime(updateCallback, i, kpidCTime, ui.CTime, ui.CTimeDefined)); - if (need_ATime) RINOK(GetTime(updateCallback, i, kpidATime, ui.ATime, ui.ATimeDefined)); - if (need_MTime) RINOK(GetTime(updateCallback, i, kpidMTime, ui.MTime, ui.MTimeDefined)); + if (need_CTime) RINOK(GetTime(updateCallback, i, kpidCTime, ui.CTime, ui.CTimeDefined)) + if (need_ATime) RINOK(GetTime(updateCallback, i, kpidATime, ui.ATime, ui.ATimeDefined)) + if (need_MTime) RINOK(GetTime(updateCallback, i, kpidMTime, ui.MTime, ui.MTimeDefined)) /* if (getRawProps) @@ -369,7 +520,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt { NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(i, kpidPath, &prop)); + RINOK(updateCallback->GetProperty(i, kpidPath, &prop)) if (prop.vt == VT_EMPTY) { } @@ -377,12 +528,13 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt return E_INVALIDARG; else { - name = NItemName::MakeLegalName(prop.bstrVal); + name = prop.bstrVal; + NItemName::ReplaceSlashes_OsToUnix(name); } } { NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(i, kpidIsDir, &prop)); + RINOK(updateCallback->GetProperty(i, kpidIsDir, &prop)) if (prop.vt == VT_EMPTY) folderStatusIsDefined = false; else if (prop.vt != VT_BOOL) @@ -396,7 +548,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt { NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(i, kpidIsAnti, &prop)); + RINOK(updateCallback->GetProperty(i, kpidIsAnti, &prop)) if (prop.vt == VT_EMPTY) ui.IsAnti = false; else if (prop.vt != VT_BOOL) @@ -513,7 +665,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt if (!ui.IsDir) { NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(i, kpidSize, &prop)); + RINOK(updateCallback->GetProperty(i, kpidSize, &prop)) if (prop.vt != VT_UI8) return E_INVALIDARG; ui.Size = (UInt64)prop.uhVal.QuadPart; @@ -537,32 +689,39 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt CCompressionMethodMode methodMode, headerMethod; - HRESULT res = SetMainMethod(methodMode - #ifndef _7ZIP_ST - , _numThreads - #endif - ); - RINOK(res); + methodMode.MemoryUsageLimit = _memUsage_Compress; + methodMode.MemoryUsageLimit_WasSet = _memUsage_WasSet; - RINOK(SetHeaderMethod(headerMethod)); - - #ifndef _7ZIP_ST - methodMode.NumThreads = _numThreads; - methodMode.MultiThreadMixer = _useMultiThreadMixer; - headerMethod.NumThreads = 1; - headerMethod.MultiThreadMixer = _useMultiThreadMixer; + #ifndef Z7_ST + { + UInt32 numThreads = _numThreads; + const UInt32 kNumThreads_Max = 1024; + if (numThreads > kNumThreads_Max) + numThreads = kNumThreads_Max; + methodMode.NumThreads = numThreads; + methodMode.NumThreads_WasForced = _numThreads_WasForced; + methodMode.MultiThreadMixer = _useMultiThreadMixer; + // headerMethod.NumThreads = 1; + headerMethod.MultiThreadMixer = _useMultiThreadMixer; + } #endif - CMyComPtr<ICryptoGetTextPassword2> getPassword2; - updateCallback->QueryInterface(IID_ICryptoGetTextPassword2, (void **)&getPassword2); + const HRESULT res = SetMainMethod(methodMode); + RINOK(res) + + RINOK(SetHeaderMethod(headerMethod)) + + Z7_DECL_CMyComPtr_QI_FROM( + ICryptoGetTextPassword2, + getPassword2, updateCallback) methodMode.PasswordIsDefined = false; - methodMode.Password.Empty(); + methodMode.Password.Wipe_and_Empty(); if (getPassword2) { - CMyComBSTR password; + CMyComBSTR_Wipe password; Int32 passwordIsDefined; - RINOK(getPassword2->CryptoGetTextPassword2(&passwordIsDefined, &password)); + RINOK(getPassword2->CryptoGetTextPassword2(&passwordIsDefined, &password)) methodMode.PasswordIsDefined = IntToBool(passwordIsDefined); if (methodMode.PasswordIsDefined && password) methodMode.Password = password; @@ -572,7 +731,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt bool encryptHeaders = false; - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO if (!methodMode.PasswordIsDefined && _passwordIsDefined) { // if header is compressed, we use that password for updated archive @@ -585,7 +744,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt { if (_encryptHeadersSpecified) encryptHeaders = _encryptHeaders; - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO else encryptHeaders = _passwordIsDefined; #endif @@ -600,9 +759,15 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt if (numItems < 2) compressMainHeader = false; - int level = GetLevel(); + const int level = GetLevel(); CUpdateOptions options; + options.Need_CTime = need_CTime; + options.Need_ATime = need_ATime; + options.Need_MTime = need_MTime; + options.Need_Attrib = need_Attrib; + // options.Need_Crc = (_crcSize != 0); // for debug + options.Method = &methodMode; options.HeaderMethod = (_compressHeaders || encryptHeaders) ? &headerMethod : NULL; options.UseFilters = (level != 0 && _autoFilter && !methodMode.Filter_was_Inserted); @@ -614,6 +779,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt options.HeaderOptions.WriteCTime = Write_CTime; options.HeaderOptions.WriteATime = Write_ATime; options.HeaderOptions.WriteMTime = Write_MTime; + options.HeaderOptions.WriteAttrib = Write_Attrib; */ options.NumSolidFiles = _numSolidFiles; @@ -626,12 +792,6 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt options.MultiThreadMixer = _useMultiThreadMixer; - COutArchive archive; - CArchiveDatabaseOut newDatabase; - - CMyComPtr<ICryptoGetTextPassword> getPassword; - updateCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&getPassword); - /* if (secureBlocks.Sorted.Size() > 1) { @@ -644,9 +804,9 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt } */ - res = Update( + return Update( EXTERNAL_CODECS_VARS - #ifdef _7Z_VOL + #ifdef Z7_7Z_VOL volume ? volume->Stream: 0, volume ? db : 0, #else @@ -656,18 +816,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt updateItems, // treeFolders, // secureBlocks, - archive, newDatabase, outStream, updateCallback, options - #ifndef _NO_CRYPTO - , getPassword - #endif - ); - - RINOK(res); - - updateItems.ClearAndFree(); - - return archive.WriteDatabase(EXTERNAL_CODECS_VARS - newDatabase, options.HeaderMethod, options.HeaderOptions); + outStream, updateCallback, options); COM_TRY_END } @@ -676,7 +825,7 @@ static HRESULT ParseBond(UString &srcString, UInt32 &coder, UInt32 &stream) { stream = 0; { - unsigned index = ParseStringToUInt32(srcString, coder); + const unsigned index = ParseStringToUInt32(srcString, coder); if (index == 0) return E_INVALIDARG; srcString.DeleteFrontal(index); @@ -684,7 +833,7 @@ static HRESULT ParseBond(UString &srcString, UInt32 &coder, UInt32 &stream) if (srcString[0] == 's') { srcString.Delete(0); - unsigned index = ParseStringToUInt32(srcString, stream); + const unsigned index = ParseStringToUInt32(srcString, stream); if (index == 0) return E_INVALIDARG; srcString.DeleteFrontal(index); @@ -692,19 +841,16 @@ static HRESULT ParseBond(UString &srcString, UInt32 &coder, UInt32 &stream) return S_OK; } -void COutHandler::InitProps() +void COutHandler::InitProps7z() { - CMultiMethodProps::Init(); - _removeSfxBlock = false; _compressHeaders = true; _encryptHeadersSpecified = false; _encryptHeaders = false; // _useParents = false; - Write_CTime.Init(); - Write_ATime.Init(); - Write_MTime.Init(); + TimeOptions.Init(); + Write_Attrib.Init(); _useMultiThreadMixer = true; @@ -714,6 +860,14 @@ void COutHandler::InitProps() _useTypeSorting = false; } +void COutHandler::InitProps() +{ + CMultiMethodProps::Init(); + InitProps7z(); +} + + + HRESULT COutHandler::SetSolidFromString(const UString &s) { UString s2 = s; @@ -730,10 +884,10 @@ HRESULT COutHandler::SetSolidFromString(const UString &s) _solidExtension = true; continue; } - i += (int)(end - start); + i += (unsigned)(end - start); if (i == s2.Len()) return E_INVALIDARG; - wchar_t c = s2[i++]; + const wchar_t c = s2[i++]; if (c == 'f') { if (v < 1) @@ -754,6 +908,10 @@ HRESULT COutHandler::SetSolidFromString(const UString &s) } _numSolidBytes = (v << numBits); _numSolidBytesDefined = true; + /* + if (_numSolidBytes == 0) + _numSolidFiles = 1; + */ } } return S_OK; @@ -781,7 +939,7 @@ HRESULT COutHandler::SetSolidFromPROPVARIANT(const PROPVARIANT &value) static HRESULT PROPVARIANT_to_BoolPair(const PROPVARIANT &prop, CBoolPair &dest) { - RINOK(PROPVARIANT_to_bool(prop, dest.Val)); + RINOK(PROPVARIANT_to_bool(prop, dest.Val)) dest.Def = true; return S_OK; } @@ -802,9 +960,9 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val return E_INVALIDARG; return SetSolidFromString(name); } - + UInt32 number; - int index = ParseStringToUInt32(name, number); + const unsigned index = ParseStringToUInt32(name, number); // UString realName = name.Ptr(index); if (index == 0) { @@ -815,20 +973,32 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val if (name.IsEqualTo("hcf")) { bool compressHeadersFull = true; - RINOK(PROPVARIANT_to_bool(value, compressHeadersFull)); + RINOK(PROPVARIANT_to_bool(value, compressHeadersFull)) return compressHeadersFull ? S_OK: E_INVALIDARG; } if (name.IsEqualTo("he")) { - RINOK(PROPVARIANT_to_bool(value, _encryptHeaders)); + RINOK(PROPVARIANT_to_bool(value, _encryptHeaders)) _encryptHeadersSpecified = true; return S_OK; } - if (name.IsEqualTo("tc")) return PROPVARIANT_to_BoolPair(value, Write_CTime); - if (name.IsEqualTo("ta")) return PROPVARIANT_to_BoolPair(value, Write_ATime); - if (name.IsEqualTo("tm")) return PROPVARIANT_to_BoolPair(value, Write_MTime); + { + bool processed; + RINOK(TimeOptions.Parse(name, value, processed)) + if (processed) + { + if ( TimeOptions.Prec != (UInt32)(Int32)-1 + && TimeOptions.Prec != k_PropVar_TimePrec_0 + && TimeOptions.Prec != k_PropVar_TimePrec_HighPrec + && TimeOptions.Prec != k_PropVar_TimePrec_100ns) + return E_INVALIDARG; + return S_OK; + } + } + + if (name.IsEqualTo("tr")) return PROPVARIANT_to_BoolPair(value, Write_Attrib); if (name.IsEqualTo("mtf")) return PROPVARIANT_to_bool(value, _useMultiThreadMixer); @@ -839,7 +1009,7 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val return CMultiMethodProps::SetProperty(name, value); } -STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps) +Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)) { COM_TRY_BEGIN _bonds.Clear(); @@ -854,6 +1024,7 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR const PROPVARIANT &value = values[i]; + if (name.Find(L':') >= 0) // 'b' was used as NCoderPropID::kBlockSize2 before v23 if (name[0] == 'b') { if (value.vt != VT_EMPTY) @@ -861,12 +1032,12 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR name.Delete(0); CBond2 bond; - RINOK(ParseBond(name, bond.OutCoder, bond.OutStream)); + RINOK(ParseBond(name, bond.OutCoder, bond.OutStream)) if (name[0] != ':') return E_INVALIDARG; name.Delete(0); UInt32 inStream = 0; - RINOK(ParseBond(name, bond.InCoder, inStream)); + RINOK(ParseBond(name, bond.InCoder, inStream)) if (inStream != 0) return E_INVALIDARG; if (!name.IsEmpty()) @@ -875,7 +1046,7 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR continue; } - RINOK(SetProperty(name, value)); + RINOK(SetProperty(name, value)) } unsigned numEmptyMethods = GetNumEmptyMethods(); @@ -911,3 +1082,5 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR } }} + +#endif diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zHeader.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zHeader.cpp index acff2fdd8d9..d5f94973b14 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zHeader.cpp +++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zHeader.cpp @@ -8,7 +8,7 @@ namespace NArchive { namespace N7z { Byte kSignature[kSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}; -#ifdef _7Z_VOL +#ifdef Z7_7Z_VOL Byte kFinishSignature[kSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C + 1}; #endif diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zHeader.h b/3rdparty/lzma/CPP/7zip/Archive/7z/7zHeader.h index d7f0ae365b9..bd96ca3c61a 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zHeader.h +++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zHeader.h @@ -1,7 +1,7 @@ // 7z/7zHeader.h -#ifndef __7Z_HEADER_H -#define __7Z_HEADER_H +#ifndef ZIP7_INC_7Z_HEADER_H +#define ZIP7_INC_7Z_HEADER_H #include "../../../Common/MyTypes.h" @@ -11,13 +11,13 @@ namespace N7z { const unsigned kSignatureSize = 6; extern Byte kSignature[kSignatureSize]; -// #define _7Z_VOL +// #define Z7_7Z_VOL // 7z-MultiVolume is not finished yet. // It can work already, but I still do not like some // things of that new multivolume format. // So please keep it commented. -#ifdef _7Z_VOL +#ifdef Z7_7Z_VOL extern Byte kFinishSignature[kSignatureSize]; #endif @@ -38,7 +38,7 @@ struct CStartHeader const UInt32 kStartHeaderSize = 20; -#ifdef _7Z_VOL +#ifdef Z7_7Z_VOL struct CFinishHeader: public CStartHeader { UInt64 ArchiveStartOffset; // data offset from end if that struct @@ -99,6 +99,7 @@ namespace NID const UInt32 k_Copy = 0; const UInt32 k_Delta = 3; +const UInt32 k_ARM64 = 0xa; const UInt32 k_LZMA2 = 0x21; @@ -108,8 +109,9 @@ const UInt32 k_SWAP4 = 0x20304; const UInt32 k_LZMA = 0x30101; const UInt32 k_PPMD = 0x30401; -const UInt32 k_Deflate = 0x40108; -const UInt32 k_BZip2 = 0x40202; +const UInt32 k_Deflate = 0x40108; +const UInt32 k_Deflate64 = 0x40109; +const UInt32 k_BZip2 = 0x40202; const UInt32 k_BCJ = 0x3030103; const UInt32 k_BCJ2 = 0x303011B; @@ -121,14 +123,17 @@ const UInt32 k_SPARC = 0x3030805; const UInt32 k_AES = 0x6F10701; +// const UInt32 k_ZSTD = 0x4015D; // winzip zstd +// 0x4F71101, 7z-zstd static inline bool IsFilterMethod(UInt64 m) { - if (m > (UInt64)0xFFFFFFFF) + if (m > (UInt32)0xFFFFFFFF) return false; switch ((UInt32)m) { case k_Delta: + case k_ARM64: case k_BCJ: case k_BCJ2: case k_PPC: diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zIn.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zIn.cpp index d8c2717501c..4defd272b39 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zIn.cpp +++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zIn.cpp @@ -11,6 +11,9 @@ #include "../../../../C/7zCrc.h" #include "../../../../C/CpuArch.h" +#include "../../../Common/MyBuffer2.h" +// #include "../../../Common/UTFConvert.h" + #include "../../Common/StreamObjects.h" #include "../../Common/StreamUtils.h" @@ -22,7 +25,7 @@ #define Get64(p) GetUi64(p) // define FORMAT_7Z_RECOVERY if you want to recover multivolume archives with empty StartHeader -#ifndef _SFX +#ifndef Z7_SFX #define FORMAT_7Z_RECOVERY #endif @@ -32,6 +35,25 @@ using namespace NCOM; namespace NArchive { namespace N7z { +#define k_Scan_NumCoders_MAX 64 +#define k_Scan_NumCodersStreams_in_Folder_MAX 64 + +unsigned BoolVector_CountSum(const CBoolVector &v); +unsigned BoolVector_CountSum(const CBoolVector &v) +{ + unsigned sum = 0; + const unsigned size = v.Size(); + for (unsigned i = 0; i < size; i++) + if (v[i]) + sum++; + return sum; +} + +static inline bool BoolVector_Item_IsValidAndTrue(const CBoolVector &v, unsigned i) +{ + return (i < v.Size() ? v[i] : false); +} + static void BoolVector_Fill_False(CBoolVector &v, unsigned size) { v.ClearAndSetSize(size); @@ -40,12 +62,17 @@ static void BoolVector_Fill_False(CBoolVector &v, unsigned size) p[i] = false; } + class CInArchiveException {}; class CUnsupportedFeatureException: public CInArchiveException {}; +Z7_ATTR_NORETURN static void ThrowException() { throw CInArchiveException(); } +Z7_ATTR_NORETURN static inline void ThrowEndOfData() { ThrowException(); } +Z7_ATTR_NORETURN static inline void ThrowUnsupported() { throw CUnsupportedFeatureException(); } +Z7_ATTR_NORETURN static inline void ThrowIncorrect() { ThrowException(); } class CStreamSwitch @@ -90,12 +117,12 @@ void CStreamSwitch::Set(CInArchive *archive, const CByteBuffer &byteBuffer) void CStreamSwitch::Set(CInArchive *archive, const CObjectVector<CByteBuffer> *dataVector) { Remove(); - Byte external = archive->ReadByte(); + const Byte external = archive->ReadByte(); if (external != 0) { if (!dataVector) ThrowIncorrect(); - CNum dataIndex = archive->ReadNum(); + const CNum dataIndex = archive->ReadNum(); if (dataIndex >= dataVector->Size()) ThrowIncorrect(); Set(archive, (*dataVector)[dataIndex]); @@ -148,7 +175,7 @@ static UInt64 ReadNumberSpec(const Byte *p, size_t size, size_t &processed) return 0; } - unsigned b = *p++; + const unsigned b = *p++; size--; if ((b & 0x80) == 0) @@ -169,10 +196,10 @@ static UInt64 ReadNumberSpec(const Byte *p, size_t size, size_t &processed) for (unsigned i = 1; i < 8; i++) { - unsigned mask = (unsigned)0x80 >> i; + const unsigned mask = (unsigned)0x80 >> i; if ((b & mask) == 0) { - UInt64 high = b & (mask - 1); + const UInt64 high = b & (mask - 1); value |= (high << (i * 8)); processed = i + 1; return value; @@ -196,7 +223,7 @@ static UInt64 ReadNumberSpec(const Byte *p, size_t size, size_t &processed) UInt64 CInByte2::ReadNumber() { size_t processed; - UInt64 res = ReadNumberSpec(_buffer + _pos, _size - _pos, processed); + const UInt64 res = ReadNumberSpec(_buffer + _pos, _size - _pos, processed); if (processed == 0) ThrowEndOfData(); _pos += processed; @@ -216,7 +243,7 @@ CNum CInByte2::ReadNum() } } */ - UInt64 value = ReadNumber(); + const UInt64 value = ReadNumber(); if (value > kNumMax) ThrowUnsupported(); return (CNum)value; @@ -226,7 +253,7 @@ UInt32 CInByte2::ReadUInt32() { if (_pos + 4 > _size) ThrowEndOfData(); - UInt32 res = Get32(_buffer + _pos); + const UInt32 res = Get32(_buffer + _pos); _pos += 4; return res; } @@ -235,54 +262,101 @@ UInt64 CInByte2::ReadUInt64() { if (_pos + 8 > _size) ThrowEndOfData(); - UInt64 res = Get64(_buffer + _pos); + const UInt64 res = Get64(_buffer + _pos); _pos += 8; return res; } -#define CHECK_SIGNATURE if (p[0] != '7' || p[1] != 'z' || p[2] != 0xBC || p[3] != 0xAF || p[4] != 0x27 || p[5] != 0x1C) return false; +#define Y0 '7' +#define Y1 'z' +#define Y2 0xBC +#define Y3 0xAF +#define Y4 0x27 +#define Y5 0x1C + +#define IS_SIGNATURE(p)( \ + (p)[2] == Y2 && \ + (p)[3] == Y3 && \ + (p)[5] == Y5 && \ + (p)[4] == Y4 && \ + (p)[1] == Y1 && \ + (p)[0] == Y0) + +/* FindSignature_10() is allowed to access data up to and including &limit[9]. + limit[10] access is not allowed. + return: + (return_ptr < limit) : signature was found at (return_ptr) + (return_ptr >= limit) : limit was reached or crossed. So no signature found before limit +*/ +Z7_NO_INLINE +static const Byte *FindSignature_10(const Byte *p, const Byte *limit) +{ + for (;;) + { + for (;;) + { + if (p >= limit) + return limit; + const Byte b = p[5]; + p += 6; + if (b == Y0) { break; } + if (b == Y1) { p -= 1; break; } + if (b == Y2) { p -= 2; break; } + if (b == Y3) { p -= 3; break; } + if (b == Y4) { p -= 4; break; } + if (b == Y5) { p -= 5; break; } + } + if (IS_SIGNATURE(p - 1)) + return p - 1; + } +} -static inline bool TestSignature(const Byte *p) + +static inline bool TestStartCrc(const Byte *p) { - CHECK_SIGNATURE return CrcCalc(p + 12, 20) == Get32(p + 8); } -#ifdef FORMAT_7Z_RECOVERY static inline bool TestSignature2(const Byte *p) { - CHECK_SIGNATURE; - if (CrcCalc(p + 12, 20) == Get32(p + 8)) + if (!IS_SIGNATURE(p)) + return false; + #ifdef FORMAT_7Z_RECOVERY + if (TestStartCrc(p)) return true; for (unsigned i = 8; i < kHeaderSize; i++) if (p[i] != 0) return false; return (p[6] != 0 || p[7] != 0); + #else + return TestStartCrc(p); + #endif } -#else -#define TestSignature2(p) TestSignature(p) -#endif + HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit) { - RINOK(ReadStream_FALSE(stream, _header, kHeaderSize)); + RINOK(ReadStream_FALSE(stream, _header, kHeaderSize)) if (TestSignature2(_header)) return S_OK; if (searchHeaderSizeLimit && *searchHeaderSizeLimit == 0) return S_FALSE; - const UInt32 kBufSize = 1 << 15; - CByteArr buf(kBufSize); + const UInt32 kBufSize = (1 << 15) + kHeaderSize; // must be > (kHeaderSize * 2) + CAlignedBuffer1 buf(kBufSize); memcpy(buf, _header, kHeaderSize); UInt64 offset = 0; for (;;) { - UInt32 readSize = kBufSize - kHeaderSize; + UInt32 readSize = + (offset == 0) ? + kBufSize - kHeaderSize - kHeaderSize : + kBufSize - kHeaderSize; if (searchHeaderSizeLimit) { - UInt64 rem = *searchHeaderSizeLimit - offset; + const UInt64 rem = *searchHeaderSizeLimit - offset; if (readSize > rem) readSize = (UInt32)rem; if (readSize == 0) @@ -290,29 +364,28 @@ HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *search } UInt32 processed = 0; - RINOK(stream->Read(buf + kHeaderSize, readSize, &processed)); + RINOK(stream->Read(buf + kHeaderSize, readSize, &processed)) if (processed == 0) return S_FALSE; + + /* &buf[0] was already tested for signature before. + So first search here will be for &buf[1] */ for (UInt32 pos = 0;;) { const Byte *p = buf + pos + 1; - const Byte *lim = buf + processed; - for (; p <= lim; p += 4) - { - if (p[0] == '7') break; - if (p[1] == '7') { p += 1; break; } - if (p[2] == '7') { p += 2; break; } - if (p[3] == '7') { p += 3; break; } - }; - if (p > lim) + const Byte *lim = buf + processed + 1; + /* we have (kHeaderSize - 1 = 31) filled bytes starting from (lim), + and it's safe to access just 10 bytes in that reserved area */ + p = FindSignature_10(p, lim); + if (p >= lim) break; pos = (UInt32)(p - buf); - if (TestSignature(p)) + if (TestStartCrc(p)) { memcpy(_header, p, kHeaderSize); _arhiveBeginStreamPosition += offset + pos; - return stream->Seek(_arhiveBeginStreamPosition + kHeaderSize, STREAM_SEEK_SET, NULL); + return InStream_SeekSet(stream, _arhiveBeginStreamPosition + kHeaderSize); } } @@ -326,10 +399,8 @@ HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit) { HeadersSize = 0; Close(); - RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_arhiveBeginStreamPosition)) - RINOK(stream->Seek(0, STREAM_SEEK_END, &_fileEndPosition)) - RINOK(stream->Seek(_arhiveBeginStreamPosition, STREAM_SEEK_SET, NULL)) - RINOK(FindAndReadSignature(stream, searchHeaderSizeLimit)); + RINOK(InStream_GetPos_GetSize(stream, _arhiveBeginStreamPosition, _fileEndPosition)) + RINOK(FindAndReadSignature(stream, searchHeaderSizeLimit)) _stream = stream; return S_OK; } @@ -355,9 +426,9 @@ void CInArchive::ReadArchiveProperties(CInArchiveInfo & /* archiveInfo */) void CInByte2::ParseFolder(CFolder &folder) { - UInt32 numCoders = ReadNum(); + const UInt32 numCoders = ReadNum(); - if (numCoders == 0) + if (numCoders == 0 || numCoders > k_Scan_NumCoders_MAX) ThrowUnsupported(); folder.Coders.SetSize(numCoders); @@ -368,10 +439,10 @@ void CInByte2::ParseFolder(CFolder &folder) { CCoderInfo &coder = folder.Coders[i]; { - Byte mainByte = ReadByte(); + const Byte mainByte = ReadByte(); if ((mainByte & 0xC0) != 0) ThrowUnsupported(); - unsigned idSize = (mainByte & 0xF); + const unsigned idSize = (mainByte & 0xF); if (idSize > 8 || idSize > GetRem()) ThrowUnsupported(); const Byte *longID = GetPtr(); @@ -384,7 +455,9 @@ void CInByte2::ParseFolder(CFolder &folder) if ((mainByte & 0x10) != 0) { coder.NumStreams = ReadNum(); + // if (coder.NumStreams > k_Scan_NumCodersStreams_in_Folder_MAX) ThrowUnsupported(); /* numOutStreams = */ ReadNum(); + // if (ReadNum() != 1) // numOutStreams ThrowUnsupported(); } else { @@ -393,7 +466,7 @@ void CInByte2::ParseFolder(CFolder &folder) if ((mainByte & 0x20) != 0) { - CNum propsSize = ReadNum(); + const CNum propsSize = ReadNum(); coder.Props.Alloc((size_t)propsSize); ReadBytes((Byte *)coder.Props, (size_t)propsSize); } @@ -403,7 +476,7 @@ void CInByte2::ParseFolder(CFolder &folder) numInStreams += coder.NumStreams; } - UInt32 numBonds = numCoders - 1; + const UInt32 numBonds = numCoders - 1; folder.Bonds.SetSize(numBonds); for (i = 0; i < numBonds; i++) { @@ -414,7 +487,7 @@ void CInByte2::ParseFolder(CFolder &folder) if (numInStreams < numBonds) ThrowUnsupported(); - UInt32 numPackStreams = numInStreams - numBonds; + const UInt32 numPackStreams = numInStreams - numBonds; folder.PackStreams.SetSize(numPackStreams); if (numPackStreams == 1) @@ -435,7 +508,7 @@ void CInByte2::ParseFolder(CFolder &folder) void CFolders::ParseFolderInfo(unsigned folderIndex, CFolder &folder) const { - size_t startPos = FoCodersDataOffset[folderIndex]; + const size_t startPos = FoCodersDataOffset[folderIndex]; CInByte2 inByte; inByte.Init(CodersData + startPos, FoCodersDataOffset[folderIndex + 1] - startPos); inByte.ParseFolder(folder); @@ -450,8 +523,8 @@ void CDatabase::GetPath(unsigned index, UString &path) const if (!NameOffsets || !NamesBuf) return; - size_t offset = NameOffsets[index]; - size_t size = NameOffsets[index + 1] - offset; + const size_t offset = NameOffsets[index]; + const size_t size = NameOffsets[index + 1] - offset; if (size >= (1 << 28)) return; @@ -462,7 +535,7 @@ void CDatabase::GetPath(unsigned index, UString &path) const #if defined(_WIN32) && defined(MY_CPU_LE) - wmemcpy(s, (const wchar_t *)p, size); + wmemcpy(s, (const wchar_t *)(const void *)p, size); #else @@ -484,16 +557,33 @@ HRESULT CDatabase::GetPath_Prop(unsigned index, PROPVARIANT *path) const throw() if (!NameOffsets || !NamesBuf) return S_OK; - size_t offset = NameOffsets[index]; - size_t size = NameOffsets[index + 1] - offset; + const size_t offset = NameOffsets[index]; + const size_t size = NameOffsets[index + 1] - offset; if (size >= (1 << 14)) return S_OK; - RINOK(PropVarEm_Alloc_Bstr(path, (unsigned)size - 1)); + // (size) includes null terminator + + /* + #if WCHAR_MAX > 0xffff + + const Byte *p = ((const Byte *)NamesBuf + offset * 2); + size = Utf16LE__Get_Num_WCHARs(p, size - 1); + // (size) doesn't include null terminator + RINOK(PropVarEm_Alloc_Bstr(path, (unsigned)size)); wchar_t *s = path->bstrVal; + wchar_t *sEnd = Utf16LE__To_WCHARs_Sep(p, size, s); + *sEnd = 0; + if (s + size != sEnd) return E_FAIL; + + #else + */ + RINOK(PropVarEm_Alloc_Bstr(path, (unsigned)size - 1)) + wchar_t *s = path->bstrVal; const Byte *p = ((const Byte *)NamesBuf + offset * 2); + // Utf16LE__To_WCHARs_Sep(p, size, s); for (size_t i = 0; i < size; i++) { @@ -502,10 +592,14 @@ HRESULT CDatabase::GetPath_Prop(unsigned index, PROPVARIANT *path) const throw() #if WCHAR_PATH_SEPARATOR != L'/' if (c == L'/') c = WCHAR_PATH_SEPARATOR; + else if (c == L'\\') + c = WCHAR_IN_FILE_NAME_BACKSLASH_REPLACEMENT; // WSL scheme #endif *s++ = c; } + // #endif + return S_OK; /* @@ -557,7 +651,7 @@ void CInArchive::WaitId(UInt64 id) { for (;;) { - UInt64 type = ReadID(); + const UInt64 type = ReadID(); if (type == id) return; if (type == NID::kEnd) @@ -566,27 +660,33 @@ void CInArchive::WaitId(UInt64 id) } } -void CInArchive::ReadHashDigests(unsigned numItems, CUInt32DefVector &crcs) + +void CInArchive::Read_UInt32_Vector(CUInt32DefVector &v) { - ReadBoolVector2(numItems, crcs.Defs); - crcs.Vals.ClearAndSetSize(numItems); - UInt32 *p = &crcs.Vals[0]; - const bool *defs = &crcs.Defs[0]; + const unsigned numItems = v.Defs.Size(); + v.Vals.ClearAndSetSize(numItems); + UInt32 *p = &v.Vals[0]; + const bool *defs = &v.Defs[0]; for (unsigned i = 0; i < numItems; i++) { - UInt32 crc = 0; + UInt32 a = 0; if (defs[i]) - crc = ReadUInt32(); - p[i] = crc; + a = ReadUInt32(); + p[i] = a; } } -#define k_Scan_NumCoders_MAX 64 -#define k_Scan_NumCodersStreams_in_Folder_MAX 64 + +void CInArchive::ReadHashDigests(unsigned numItems, CUInt32DefVector &crcs) +{ + ReadBoolVector2(numItems, crcs.Defs); + Read_UInt32_Vector(crcs); +} + void CInArchive::ReadPackInfo(CFolders &f) { - CNum numPackStreams = ReadNum(); + const CNum numPackStreams = ReadNum(); WaitId(NID::kSize); f.PackPositions.Alloc(numPackStreams + 1); @@ -595,7 +695,7 @@ void CInArchive::ReadPackInfo(CFolders &f) for (CNum i = 0; i < numPackStreams; i++) { f.PackPositions[i] = sum; - UInt64 packSize = ReadNumber(); + const UInt64 packSize = ReadNumber(); sum += packSize; if (sum < packSize) ThrowIncorrect(); @@ -623,7 +723,7 @@ void CInArchive::ReadUnpackInfo( CFolders &folders) { WaitId(NID::kFolder); - CNum numFolders = ReadNum(); + const CNum numFolders = ReadNum(); CNum numCodersOutStreams = 0; { @@ -648,21 +748,21 @@ void CInArchive::ReadUnpackInfo( { UInt32 indexOfMainStream = 0; UInt32 numPackStreams = 0; - folders.FoCodersDataOffset[fo] = _inByteBack->GetPtr() - startBufPtr; + folders.FoCodersDataOffset[fo] = (size_t)(_inByteBack->GetPtr() - startBufPtr); CNum numInStreams = 0; - CNum numCoders = inByte->ReadNum(); + const CNum numCoders = inByte->ReadNum(); if (numCoders == 0 || numCoders > k_Scan_NumCoders_MAX) ThrowUnsupported(); for (CNum ci = 0; ci < numCoders; ci++) { - Byte mainByte = inByte->ReadByte(); + const Byte mainByte = inByte->ReadByte(); if ((mainByte & 0xC0) != 0) ThrowUnsupported(); - unsigned idSize = (mainByte & 0xF); + const unsigned idSize = (mainByte & 0xF); if (idSize > 8) ThrowUnsupported(); if (idSize > inByte->GetRem()) @@ -691,18 +791,18 @@ void CInArchive::ReadUnpackInfo( if ((mainByte & 0x20) != 0) { - CNum propsSize = inByte->ReadNum(); + const CNum propsSize = inByte->ReadNum(); if (propsSize > inByte->GetRem()) ThrowEndOfData(); if (id == k_LZMA2 && propsSize == 1) { - Byte v = *_inByteBack->GetPtr(); + const Byte v = *_inByteBack->GetPtr(); if (folders.ParsedMethods.Lzma2Prop < v) folders.ParsedMethods.Lzma2Prop = v; } else if (id == k_LZMA && propsSize == 5) { - UInt32 dicSize = GetUi32(_inByteBack->GetPtr() + 1); + const UInt32 dicSize = GetUi32(_inByteBack->GetPtr() + 1); if (folders.ParsedMethods.LzmaDic < dicSize) folders.ParsedMethods.LzmaDic = dicSize; } @@ -718,7 +818,7 @@ void CInArchive::ReadUnpackInfo( else { UInt32 i; - CNum numBonds = numCoders - 1; + const CNum numBonds = numCoders - 1; if (numInStreams < numBonds) ThrowUnsupported(); @@ -743,7 +843,7 @@ void CInArchive::ReadUnpackInfo( if (numPackStreams != 1) for (i = 0; i < numPackStreams; i++) { - CNum index = inByte->ReadNum(); // PackStreams + const CNum index = inByte->ReadNum(); // PackStreams if (index >= numInStreams || StreamUsed[index]) ThrowUnsupported(); StreamUsed[index] = true; @@ -769,10 +869,10 @@ void CInArchive::ReadUnpackInfo( folders.FoToMainUnpackSizeIndex[fo] = (Byte)indexOfMainStream; } - size_t dataSize = _inByteBack->GetPtr() - startBufPtr; + const size_t dataSize = (size_t)(_inByteBack->GetPtr() - startBufPtr); folders.FoToCoderUnpackSizes[fo] = numCodersOutStreams; folders.FoStartPackStreamIndex[fo] = packStreamIndex; - folders.FoCodersDataOffset[fo] = _inByteBack->GetPtr() - startBufPtr; + folders.FoCodersDataOffset[fo] = (size_t)(_inByteBack->GetPtr() - startBufPtr); folders.CodersData.CopyFrom(startBufPtr, dataSize); // if (folders.NumPackStreams != packStreamIndex) ThrowUnsupported(); @@ -785,7 +885,7 @@ void CInArchive::ReadUnpackInfo( for (;;) { - UInt64 type = ReadID(); + const UInt64 type = ReadID(); if (type == NID::kEnd) return; if (type == NID::kCRC) @@ -829,19 +929,19 @@ void CInArchive::ReadSubStreamsInfo( { // v3.13 incorrectly worked with empty folders // v4.07: we check that folder is empty - CNum numSubstreams = folders.NumUnpackStreamsVector[i]; + const CNum numSubstreams = folders.NumUnpackStreamsVector[i]; if (numSubstreams == 0) continue; UInt64 sum = 0; for (CNum j = 1; j < numSubstreams; j++) { - UInt64 size = ReadNumber(); + const UInt64 size = ReadNumber(); unpackSizes.Add(size); sum += size; if (sum < size) ThrowIncorrect(); } - UInt64 folderUnpackSize = folders.GetFolderUnpackSize(i); + const UInt64 folderUnpackSize = folders.GetFolderUnpackSize(i); if (folderUnpackSize < sum) ThrowIncorrect(); unpackSizes.Add(folderUnpackSize - sum); @@ -854,7 +954,7 @@ void CInArchive::ReadSubStreamsInfo( { /* v9.26 - v9.29 incorrectly worked: if (folders.NumUnpackStreamsVector[i] == 0), it threw error */ - CNum val = folders.NumUnpackStreamsVector[i]; + const CNum val = folders.NumUnpackStreamsVector[i]; if (val > 1) ThrowIncorrect(); if (val == 1) @@ -865,7 +965,7 @@ void CInArchive::ReadSubStreamsInfo( unsigned numDigests = 0; for (i = 0; i < folders.NumFolders; i++) { - CNum numSubstreams = folders.NumUnpackStreamsVector[i]; + const CNum numSubstreams = folders.NumUnpackStreamsVector[i]; if (numSubstreams != 1 || !folders.FolderCRCs.ValidAndDefined(i)) numDigests += numSubstreams; } @@ -888,7 +988,7 @@ void CInArchive::ReadSubStreamsInfo( for (i = 0; i < folders.NumFolders; i++) { - CNum numSubstreams = folders.NumUnpackStreamsVector[i]; + const CNum numSubstreams = folders.NumUnpackStreamsVector[i]; if (numSubstreams == 1 && folders.FolderCRCs.ValidAndDefined(i)) { digests.Defs[k] = true; @@ -920,7 +1020,7 @@ void CInArchive::ReadSubStreamsInfo( unsigned k = 0; for (i = 0; i < folders.NumFolders; i++) { - CNum numSubstreams = folders.NumUnpackStreamsVector[i]; + const CNum numSubstreams = folders.NumUnpackStreamsVector[i]; if (numSubstreams == 1 && folders.FolderCRCs.ValidAndDefined(i)) { digests.Defs[k] = true; @@ -937,6 +1037,8 @@ void CInArchive::ReadSubStreamsInfo( } } + + void CInArchive::ReadStreamsInfo( const CObjectVector<CByteBuffer> *dataVector, UInt64 &dataOffset, @@ -949,7 +1051,11 @@ void CInArchive::ReadStreamsInfo( if (type == NID::kPackInfo) { dataOffset = ReadNumber(); + if (dataOffset > _rangeLimit) + ThrowIncorrect(); ReadPackInfo(folders); + if (folders.PackPositions[folders.NumPackStreams] > _rangeLimit - dataOffset) + ThrowIncorrect(); type = ReadID(); } @@ -1004,13 +1110,13 @@ void CInArchive::ReadBoolVector(unsigned numItems, CBoolVector &v) mask = 0x80; } p[i] = ((b & mask) != 0); - mask >>= 1; + mask = (Byte)(mask >> 1); } } void CInArchive::ReadBoolVector2(unsigned numItems, CBoolVector &v) { - Byte allAreDefined = ReadByte(); + const Byte allAreDefined = ReadByte(); if (allAreDefined == 0) { ReadBoolVector(numItems, v); @@ -1047,7 +1153,7 @@ HRESULT CInArchive::ReadAndDecodePackedStreams( DECL_EXTERNAL_CODECS_LOC_VARS UInt64 baseOffset, UInt64 &dataOffset, CObjectVector<CByteBuffer> &dataVector - _7Z_DECODER_CRYPRO_VARS_DECL + Z7_7Z_DECODER_CRYPRO_VARS_DECL ) { CFolders folders; @@ -1065,8 +1171,8 @@ HRESULT CInArchive::ReadAndDecodePackedStreams( for (CNum i = 0; i < folders.NumFolders; i++) { CByteBuffer &data = dataVector.AddNew(); - UInt64 unpackSize64 = folders.GetFolderUnpackSize(i); - size_t unpackSize = (size_t)unpackSize64; + const UInt64 unpackSize64 = folders.GetFolderUnpackSize(i); + const size_t unpackSize = (size_t)unpackSize64; if (unpackSize != unpackSize64) ThrowUnsupported(); data.Alloc(unpackSize); @@ -1075,24 +1181,36 @@ HRESULT CInArchive::ReadAndDecodePackedStreams( CMyComPtr<ISequentialOutStream> outStream = outStreamSpec; outStreamSpec->Init(data, unpackSize); + bool dataAfterEnd_Error = false; + HRESULT result = decoder.Decode( EXTERNAL_CODECS_LOC_VARS _stream, baseOffset + dataOffset, folders, i, - NULL, // *unpackSize + NULL, // &unpackSize64 outStream, NULL, // *compressProgress + NULL // **inStreamMainRes + , dataAfterEnd_Error - _7Z_DECODER_CRYPRO_VARS - #if !defined(_7ZIP_ST) && !defined(_SFX) + Z7_7Z_DECODER_CRYPRO_VARS + #if !defined(Z7_ST) , false // mtMode , 1 // numThreads + , 0 // memUsage #endif ); - RINOK(result); + RINOK(result) + + if (dataAfterEnd_Error) + ThereIsHeaderError = true; + + if (unpackSize != outStreamSpec->GetPos()) + ThrowIncorrect(); + if (folders.FolderCRCs.ValidAndDefined(i)) if (CrcCalc(data, unpackSize) != folders.FolderCRCs.Vals[i]) ThrowIncorrect(); @@ -1107,7 +1225,7 @@ HRESULT CInArchive::ReadAndDecodePackedStreams( HRESULT CInArchive::ReadHeader( DECL_EXTERNAL_CODECS_LOC_VARS CDbEx &db - _7Z_DECODER_CRYPRO_VARS_DECL + Z7_7Z_DECODER_CRYPRO_VARS_DECL ) { UInt64 type = ReadID(); @@ -1122,14 +1240,14 @@ HRESULT CInArchive::ReadHeader( if (type == NID::kAdditionalStreamsInfo) { - HRESULT result = ReadAndDecodePackedStreams( + const HRESULT result = ReadAndDecodePackedStreams( EXTERNAL_CODECS_LOC_VARS db.ArcInfo.StartPositionAfterHeader, db.ArcInfo.DataStartPosition2, dataVector - _7Z_DECODER_CRYPRO_VARS + Z7_7Z_DECODER_CRYPRO_VARS ); - RINOK(result); + RINOK(result) db.ArcInfo.DataStartPosition2 += db.ArcInfo.StartPositionAfterHeader; type = ReadID(); } @@ -1148,19 +1266,10 @@ HRESULT CInArchive::ReadHeader( type = ReadID(); } - db.Files.Clear(); - if (type == NID::kFilesInfo) { const CNum numFiles = ReadNum(); - db.Files.ClearAndSetSize(numFiles); - /* - db.Files.Reserve(numFiles); - CNum i; - for (i = 0; i < numFiles; i++) - db.Files.Add(CFileItem()); - */ db.ArcInfo.FileInfoPopIDs.Add(NID::kSize); // if (!db.PackSizes.IsEmpty()) @@ -1169,7 +1278,6 @@ HRESULT CInArchive::ReadHeader( db.ArcInfo.FileInfoPopIDs.Add(NID::kCRC); CBoolVector emptyStreamVector; - BoolVector_Fill_False(emptyStreamVector, (unsigned)numFiles); CBoolVector emptyFileVector; CBoolVector antiFileVector; CNum numEmptyStreams = 0; @@ -1179,7 +1287,7 @@ HRESULT CInArchive::ReadHeader( const UInt64 type2 = ReadID(); if (type2 == NID::kEnd) break; - UInt64 size = ReadNumber(); + const UInt64 size = ReadNumber(); if (size > _inByteBack->GetRem()) ThrowIncorrect(); CStreamSwitch switchProp; @@ -1194,16 +1302,16 @@ HRESULT CInArchive::ReadHeader( { CStreamSwitch streamSwitch; streamSwitch.Set(this, &dataVector); - size_t rem = _inByteBack->GetRem(); + const size_t rem = _inByteBack->GetRem(); db.NamesBuf.Alloc(rem); ReadBytes(db.NamesBuf, rem); - db.NameOffsets.Alloc(db.Files.Size() + 1); + db.NameOffsets.Alloc(numFiles + 1); size_t pos = 0; unsigned i; - for (i = 0; i < db.Files.Size(); i++) + for (i = 0; i < numFiles; i++) { - size_t curRem = (rem - pos) / 2; - const UInt16 *buf = (const UInt16 *)(db.NamesBuf + pos); + const size_t curRem = (rem - pos) / 2; + const UInt16 *buf = (const UInt16 *)(const void *)(db.NamesBuf + pos); size_t j; for (j = 0; j < curRem && buf[j] != 0; j++); if (j == curRem) @@ -1216,36 +1324,31 @@ HRESULT CInArchive::ReadHeader( ThereIsHeaderError = true; break; } + case NID::kWinAttrib: { - CBoolVector boolVector; - ReadBoolVector2(db.Files.Size(), boolVector); + ReadBoolVector2(numFiles, db.Attrib.Defs); CStreamSwitch streamSwitch; streamSwitch.Set(this, &dataVector); - for (CNum i = 0; i < numFiles; i++) - { - CFileItem &file = db.Files[i]; - file.AttribDefined = boolVector[i]; - if (file.AttribDefined) - file.Attrib = ReadUInt32(); - } + Read_UInt32_Vector(db.Attrib); break; } + /* case NID::kIsAux: { - ReadBoolVector(db.Files.Size(), db.IsAux); + ReadBoolVector(numFiles, db.IsAux); break; } case NID::kParent: { db.IsTree = true; // CBoolVector boolVector; - // ReadBoolVector2(db.Files.Size(), boolVector); + // ReadBoolVector2(numFiles, boolVector); // CStreamSwitch streamSwitch; // streamSwitch.Set(this, &dataVector); CBoolVector boolVector; - ReadBoolVector2(db.Files.Size(), boolVector); + ReadBoolVector2(numFiles, boolVector); db.ThereAreAltStreams = false; for (i = 0; i < numFiles; i++) @@ -1264,14 +1367,9 @@ HRESULT CInArchive::ReadHeader( case NID::kEmptyStream: { ReadBoolVector(numFiles, emptyStreamVector); - numEmptyStreams = 0; - for (CNum i = 0; i < (CNum)emptyStreamVector.Size(); i++) - if (emptyStreamVector[i]) - numEmptyStreams++; - - BoolVector_Fill_False(emptyFileVector, numEmptyStreams); - BoolVector_Fill_False(antiFileVector, numEmptyStreams); - + numEmptyStreams = BoolVector_CountSum(emptyStreamVector); + emptyFileVector.Clear(); + antiFileVector.Clear(); break; } case NID::kEmptyFile: ReadBoolVector(numEmptyStreams, emptyFileVector); break; @@ -1314,7 +1412,7 @@ HRESULT CInArchive::ReadHeader( ReadBytes(db.SecureBuf + offset, db.SecureOffsets[i + 1] - offset); } db.SecureIDs.Clear(); - for (unsigned i = 0; i < db.Files.Size(); i++) + for (unsigned i = 0; i < numFiles; i++) { db.SecureIDs.Add(ReadNum()); // db.SecureIDs.Add(ReadUInt32()); @@ -1359,22 +1457,21 @@ HRESULT CInArchive::ReadHeader( CNum emptyFileIndex = 0; CNum sizeIndex = 0; - CNum numAntiItems = 0; + const CNum numAntiItems = BoolVector_CountSum(antiFileVector); - CNum i; + if (numAntiItems != 0) + db.IsAnti.ClearAndSetSize(numFiles); - for (i = 0; i < numEmptyStreams; i++) - if (antiFileVector[i]) - numAntiItems++; + db.Files.ClearAndSetSize(numFiles); - for (i = 0; i < numFiles; i++) + for (CNum i = 0; i < numFiles; i++) { CFileItem &file = db.Files[i]; bool isAnti; - file.HasStream = !emptyStreamVector[i]; file.Crc = 0; - if (file.HasStream) + if (!BoolVector_Item_IsValidAndTrue(emptyStreamVector, i)) { + file.HasStream = true; file.IsDir = false; isAnti = false; file.Size = unpackSizes[sizeIndex]; @@ -1385,26 +1482,31 @@ HRESULT CInArchive::ReadHeader( } else { - file.IsDir = !emptyFileVector[emptyFileIndex]; - isAnti = antiFileVector[emptyFileIndex]; + file.HasStream = false; + file.IsDir = !BoolVector_Item_IsValidAndTrue(emptyFileVector, emptyFileIndex); + isAnti = BoolVector_Item_IsValidAndTrue(antiFileVector, emptyFileIndex); emptyFileIndex++; file.Size = 0; file.CrcDefined = false; } if (numAntiItems != 0) - db.IsAnti.Add(isAnti); + db.IsAnti[i] = isAnti; } + } + db.FillLinks(); - /* - if (type != NID::kEnd) - ThrowIncorrect(); - if (_inByteBack->GetRem() != 0) - ThrowIncorrect(); - */ + + if (type != NID::kEnd || _inByteBack->GetRem() != 0) + { + db.UnsupportedFeatureWarning = true; + // ThrowIncorrect(); + } + return S_OK; } + void CDbEx::FillLinks() { FolderStartFileIndex.Alloc(NumFolders); @@ -1416,7 +1518,7 @@ void CDbEx::FillLinks() for (i = 0; i < Files.Size(); i++) { - bool emptyStream = !Files[i].HasStream; + const bool emptyStream = !Files[i].HasStream; if (indexInFolder == 0) { if (emptyStream) @@ -1447,29 +1549,33 @@ void CDbEx::FillLinks() } if (indexInFolder != 0) + { folderIndex++; - /* - if (indexInFolder != 0) - ThrowIncorrect(); - */ + // 18.06 + ThereIsHeaderError = true; + // ThrowIncorrect(); + } for (;;) { if (folderIndex >= NumFolders) return; FolderStartFileIndex[folderIndex] = i; - /* if (NumUnpackStreamsVector[folderIndex] != 0) - ThrowIncorrect();; - */ + { + // 18.06 + ThereIsHeaderError = true; + // ThrowIncorrect(); + } folderIndex++; } } + HRESULT CInArchive::ReadDatabase2( DECL_EXTERNAL_CODECS_LOC_VARS CDbEx &db - _7Z_DECODER_CRYPRO_VARS_DECL + Z7_7Z_DECODER_CRYPRO_VARS_DECL ) { db.Clear(); @@ -1489,22 +1595,22 @@ HRESULT CInArchive::ReadDatabase2( UInt32 nextHeaderCRC = Get32(_header + 28); #ifdef FORMAT_7Z_RECOVERY - UInt32 crcFromArc = Get32(_header + 8); + const UInt32 crcFromArc = Get32(_header + 8); if (crcFromArc == 0 && nextHeaderOffset == 0 && nextHeaderSize == 0 && nextHeaderCRC == 0) { UInt64 cur, fileSize; - RINOK(_stream->Seek(0, STREAM_SEEK_CUR, &cur)); + RINOK(InStream_GetPos(_stream, cur)) const unsigned kCheckSize = 512; Byte buf[kCheckSize]; - RINOK(_stream->Seek(0, STREAM_SEEK_END, &fileSize)); - UInt64 rem = fileSize - cur; + RINOK(InStream_GetSize_SeekToEnd(_stream, fileSize)) + const UInt64 rem = fileSize - cur; unsigned checkSize = kCheckSize; if (rem < kCheckSize) checkSize = (unsigned)(rem); if (checkSize < 3) return S_FALSE; - RINOK(_stream->Seek(fileSize - checkSize, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(_stream, buf, (size_t)checkSize)); + RINOK(InStream_SeekSet(_stream, fileSize - checkSize)) + RINOK(ReadStream_FALSE(_stream, buf, (size_t)checkSize)) if (buf[checkSize - 1] != 0) return S_FALSE; @@ -1512,8 +1618,8 @@ HRESULT CInArchive::ReadDatabase2( unsigned i; for (i = checkSize - 2;; i--) { - if (buf[i] == NID::kEncodedHeader && buf[i + 1] == NID::kPackInfo || - buf[i] == NID::kHeader && buf[i + 1] == NID::kMainStreamsInfo) + if ((buf[i] == NID::kEncodedHeader && buf[i + 1] == NID::kPackInfo) || + (buf[i] == NID::kHeader && buf[i + 1] == NID::kMainStreamsInfo)) break; if (i == 0) return S_FALSE; @@ -1521,7 +1627,7 @@ HRESULT CInArchive::ReadDatabase2( nextHeaderSize = checkSize - i; nextHeaderOffset = rem - nextHeaderSize; nextHeaderCRC = CrcCalc(buf + i, (size_t)nextHeaderSize); - RINOK(_stream->Seek(cur, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(_stream, cur)) db.StartHeaderWasRecovered = true; } else @@ -1538,32 +1644,39 @@ HRESULT CInArchive::ReadDatabase2( if ((Int64)nextHeaderOffset < 0 || nextHeaderSize > ((UInt64)1 << 62)) return S_FALSE; + + HeadersSize = kHeaderSize; + if (nextHeaderSize == 0) { if (nextHeaderOffset != 0) return S_FALSE; db.IsArc = true; + db.HeadersSize = HeadersSize; return S_OK; } if (!db.StartHeaderWasRecovered) db.IsArc = true; - HeadersSize += kHeaderSize + nextHeaderSize; + HeadersSize += nextHeaderSize; + // db.EndHeaderOffset = nextHeaderOffset; + _rangeLimit = nextHeaderOffset; + db.PhySize = kHeaderSize + nextHeaderOffset + nextHeaderSize; if (_fileEndPosition - db.ArcInfo.StartPositionAfterHeader < nextHeaderOffset + nextHeaderSize) { db.UnexpectedEnd = true; return S_FALSE; } - RINOK(_stream->Seek(nextHeaderOffset, STREAM_SEEK_CUR, NULL)); + RINOK(_stream->Seek((Int64)nextHeaderOffset, STREAM_SEEK_CUR, NULL)) - size_t nextHeaderSize_t = (size_t)nextHeaderSize; + const size_t nextHeaderSize_t = (size_t)nextHeaderSize; if (nextHeaderSize_t != nextHeaderSize) return E_OUTOFMEMORY; CByteBuffer buffer2(nextHeaderSize_t); - RINOK(ReadStream_FALSE(_stream, buffer2, nextHeaderSize_t)); + RINOK(ReadStream_FALSE(_stream, buffer2, nextHeaderSize_t)) if (CrcCalc(buffer2, nextHeaderSize_t) != nextHeaderCRC) ThrowIncorrect(); @@ -1576,19 +1689,19 @@ HRESULT CInArchive::ReadDatabase2( CObjectVector<CByteBuffer> dataVector; - UInt64 type = ReadID(); + const UInt64 type = ReadID(); if (type != NID::kHeader) { if (type != NID::kEncodedHeader) ThrowIncorrect(); - HRESULT result = ReadAndDecodePackedStreams( + const HRESULT result = ReadAndDecodePackedStreams( EXTERNAL_CODECS_LOC_VARS db.ArcInfo.StartPositionAfterHeader, db.ArcInfo.DataStartPosition2, dataVector - _7Z_DECODER_CRYPRO_VARS + Z7_7Z_DECODER_CRYPRO_VARS ); - RINOK(result); + RINOK(result) if (dataVector.Size() == 0) return S_OK; if (dataVector.Size() > 1) @@ -1606,21 +1719,22 @@ HRESULT CInArchive::ReadDatabase2( return ReadHeader( EXTERNAL_CODECS_LOC_VARS db - _7Z_DECODER_CRYPRO_VARS + Z7_7Z_DECODER_CRYPRO_VARS ); } + HRESULT CInArchive::ReadDatabase( DECL_EXTERNAL_CODECS_LOC_VARS CDbEx &db - _7Z_DECODER_CRYPRO_VARS_DECL + Z7_7Z_DECODER_CRYPRO_VARS_DECL ) { try { - HRESULT res = ReadDatabase2( + const HRESULT res = ReadDatabase2( EXTERNAL_CODECS_LOC_VARS db - _7Z_DECODER_CRYPRO_VARS + Z7_7Z_DECODER_CRYPRO_VARS ); if (ThereIsHeaderError) db.ThereIsHeaderError = true; diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zIn.h b/3rdparty/lzma/CPP/7zip/Archive/7z/7zIn.h index 3592e99b530..a9c14fb3b88 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zIn.h +++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zIn.h @@ -1,7 +1,7 @@ // 7zIn.h -#ifndef __7Z_IN_H -#define __7Z_IN_H +#ifndef ZIP7_INC_7Z_IN_H +#define ZIP7_INC_7Z_IN_H #include "../../../Common/MyCom.h" @@ -22,12 +22,12 @@ namespace N7z { We don't need to init isEncrypted and passwordIsDefined We must upgrade them only */ -#ifdef _NO_CRYPTO -#define _7Z_DECODER_CRYPRO_VARS_DECL -#define _7Z_DECODER_CRYPRO_VARS +#ifdef Z7_NO_CRYPTO +#define Z7_7Z_DECODER_CRYPRO_VARS_DECL +#define Z7_7Z_DECODER_CRYPRO_VARS #else -#define _7Z_DECODER_CRYPRO_VARS_DECL , ICryptoGetTextPassword *getTextPassword, bool &isEncrypted, bool &passwordIsDefined, UString &password -#define _7Z_DECODER_CRYPRO_VARS , getTextPassword, isEncrypted, passwordIsDefined, password +#define Z7_7Z_DECODER_CRYPRO_VARS_DECL , ICryptoGetTextPassword *getTextPassword, bool &isEncrypted, bool &passwordIsDefined, UString &password +#define Z7_7Z_DECODER_CRYPRO_VARS , getTextPassword, isEncrypted, passwordIsDefined, password #endif struct CParsedMethods @@ -115,6 +115,7 @@ struct CDatabase: public CFolders CUInt64DefVector ATime; CUInt64DefVector MTime; CUInt64DefVector StartPos; + CUInt32DefVector Attrib; CBoolVector IsAnti; /* CBoolVector IsAux; @@ -146,6 +147,7 @@ struct CDatabase: public CFolders ATime.Clear(); MTime.Clear(); StartPos.Clear(); + Attrib.Clear(); IsAnti.Clear(); // IsAux.Clear(); } @@ -172,13 +174,14 @@ struct CDatabase: public CFolders HRESULT GetPath_Prop(unsigned index, PROPVARIANT *path) const throw(); }; + struct CInArchiveInfo { CArchiveVersion Version; - UInt64 StartPosition; - UInt64 StartPositionAfterHeader; - UInt64 DataStartPosition; - UInt64 DataStartPosition2; + UInt64 StartPosition; // in stream + UInt64 StartPositionAfterHeader; // in stream + UInt64 DataStartPosition; // in stream + UInt64 DataStartPosition2; // in stream. it's for headers CRecordVector<UInt64> FileInfoPopIDs; void Clear() @@ -191,6 +194,7 @@ struct CInArchiveInfo } }; + struct CDbEx: public CDatabase { CInArchiveInfo ArcInfo; @@ -200,6 +204,7 @@ struct CDbEx: public CDatabase UInt64 HeadersSize; UInt64 PhySize; + // UInt64 EndHeaderOffset; // relative to position after StartHeader (32 bytes) /* CRecordVector<size_t> SecureOffsets; @@ -253,6 +258,17 @@ struct CDbEx: public CDatabase HeadersSize = 0; PhySize = 0; + // EndHeaderOffset = 0; + } + + bool CanUpdate() const + { + if (ThereIsHeaderError + || UnexpectedEnd + || StartHeaderWasRecovered + || UnsupportedFeatureError) + return false; + return true; } void FillLinks(); @@ -337,6 +353,8 @@ class CInArchive UInt64 _arhiveBeginStreamPosition; UInt64 _fileEndPosition; + UInt64 _rangeLimit; // relative to position after StartHeader (32 bytes) + Byte _header[kHeaderSize]; UInt64 HeadersSize; @@ -369,6 +387,8 @@ class CInArchive void SkipData() { _inByteBack->SkipData(); } void WaitId(UInt64 id); + void Read_UInt32_Vector(CUInt32DefVector &v); + void ReadArchiveProperties(CInArchiveInfo &archiveInfo); void ReadHashDigests(unsigned numItems, CUInt32DefVector &crcs); @@ -398,17 +418,17 @@ class CInArchive DECL_EXTERNAL_CODECS_LOC_VARS UInt64 baseOffset, UInt64 &dataOffset, CObjectVector<CByteBuffer> &dataVector - _7Z_DECODER_CRYPRO_VARS_DECL + Z7_7Z_DECODER_CRYPRO_VARS_DECL ); HRESULT ReadHeader( DECL_EXTERNAL_CODECS_LOC_VARS CDbEx &db - _7Z_DECODER_CRYPRO_VARS_DECL + Z7_7Z_DECODER_CRYPRO_VARS_DECL ); HRESULT ReadDatabase2( DECL_EXTERNAL_CODECS_LOC_VARS CDbEx &db - _7Z_DECODER_CRYPRO_VARS_DECL + Z7_7Z_DECODER_CRYPRO_VARS_DECL ); public: CInArchive(bool useMixerMT): @@ -422,7 +442,7 @@ public: HRESULT ReadDatabase( DECL_EXTERNAL_CODECS_LOC_VARS CDbEx &db - _7Z_DECODER_CRYPRO_VARS_DECL + Z7_7Z_DECODER_CRYPRO_VARS_DECL ); }; diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zItem.h b/3rdparty/lzma/CPP/7zip/Archive/7z/7zItem.h index 5e2b58f2ef4..e8c68bee1e5 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zItem.h +++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zItem.h @@ -1,7 +1,7 @@ // 7zItem.h -#ifndef __7Z_ITEM_H -#define __7Z_ITEM_H +#ifndef ZIP7_INC_7Z_ITEM_H +#define ZIP7_INC_7Z_ITEM_H #include "../../../Common/MyBuffer.h" #include "../../../Common/MyString.h" @@ -26,15 +26,17 @@ struct CCoderInfo bool IsSimpleCoder() const { return NumStreams == 1; } }; + struct CBond { UInt32 PackIndex; UInt32 UnpackIndex; }; + struct CFolder { - CLASS_NO_COPY(CFolder) + Z7_CLASS_NO_COPY(CFolder) public: CObjArray2<CCoderInfo> Coders; CObjArray2<CBond> Bonds; @@ -48,7 +50,7 @@ public: { FOR_VECTOR(i, PackStreams) if (PackStreams[i] == packStream) - return i; + return (int)i; return -1; } @@ -56,7 +58,7 @@ public: { FOR_VECTOR(i, Bonds) if (Bonds[i].PackIndex == packStream) - return i; + return (int)i; return -1; } @@ -87,6 +89,7 @@ public: } }; + struct CUInt32DefVector { CBoolVector Defs; @@ -110,9 +113,30 @@ struct CUInt32DefVector Vals.ReserveDown(); } + bool GetItem(unsigned index, UInt32 &value) const + { + if (index < Defs.Size() && Defs[index]) + { + value = Vals[index]; + return true; + } + value = 0; + return false; + } + bool ValidAndDefined(unsigned i) const { return i < Defs.Size() && Defs[i]; } + + bool CheckSize(unsigned size) const { return Defs.Size() == size || Defs.Size() == 0; } + + void SetItem(unsigned index, bool defined, UInt32 value); + void if_NonEmpty_FillResedue_with_false(unsigned numItems) + { + if (Defs.Size() != 0 && Defs.Size() < numItems) + SetItem(numItems - 1, false, 0); + } }; + struct CUInt64DefVector { CBoolVector Defs; @@ -141,15 +165,15 @@ struct CUInt64DefVector return false; } - void SetItem(unsigned index, bool defined, UInt64 value); - bool CheckSize(unsigned size) const { return Defs.Size() == size || Defs.Size() == 0; } + + void SetItem(unsigned index, bool defined, UInt64 value); }; + struct CFileItem { UInt64 Size; - UInt32 Attrib; UInt32 Crc; /* int Parent; @@ -159,23 +183,23 @@ struct CFileItem // stream in some folder. It can be empty stream bool IsDir; bool CrcDefined; - bool AttribDefined; + + /* + void Clear() + { + HasStream = true; + IsDir = false; + CrcDefined = false; + } CFileItem(): - /* - Parent(-1), - IsAltStream(false), - */ + // Parent(-1), + // IsAltStream(false), HasStream(true), IsDir(false), CrcDefined(false), - AttribDefined(false) {} - void SetAttrib(UInt32 attrib) - { - AttribDefined = true; - Attrib = attrib; - } + */ }; }} diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zOut.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zOut.cpp index 3e70f466e7b..7f8fa5b5229 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zOut.cpp +++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zOut.cpp @@ -5,6 +5,7 @@ #include "../../../../C/7zCrc.h" #include "../../../Common/AutoPtr.h" +// #include "../../../Common/UTFConvert.h" #include "../../Common/StreamObjects.h" @@ -13,16 +14,14 @@ namespace NArchive { namespace N7z { -HRESULT COutArchive::WriteSignature() +static void FillSignature(Byte *buf) { - Byte buf[8]; memcpy(buf, kSignature, kSignatureSize); buf[kSignatureSize] = kMajorVersion; buf[kSignatureSize + 1] = 4; - return WriteDirect(buf, 8); } -#ifdef _7Z_VOL +#ifdef Z7_7Z_VOL HRESULT COutArchive::WriteFinishSignature() { RINOK(WriteDirect(kFinishSignature, kSignatureSize)); @@ -48,15 +47,16 @@ static void SetUInt64(Byte *p, UInt64 d) HRESULT COutArchive::WriteStartHeader(const CStartHeader &h) { - Byte buf[24]; - SetUInt64(buf + 4, h.NextHeaderOffset); - SetUInt64(buf + 12, h.NextHeaderSize); - SetUInt32(buf + 20, h.NextHeaderCRC); - SetUInt32(buf, CrcCalc(buf + 4, 20)); - return WriteDirect(buf, 24); + Byte buf[32]; + FillSignature(buf); + SetUInt64(buf + 8 + 4, h.NextHeaderOffset); + SetUInt64(buf + 8 + 12, h.NextHeaderSize); + SetUInt32(buf + 8 + 20, h.NextHeaderCRC); + SetUInt32(buf + 8, CrcCalc(buf + 8 + 4, 20)); + return WriteDirect(buf, sizeof(buf)); } -#ifdef _7Z_VOL +#ifdef Z7_7Z_VOL HRESULT COutArchive::WriteFinishHeader(const CFinishHeader &h) { CCRC crc; @@ -74,15 +74,15 @@ HRESULT COutArchive::WriteFinishHeader(const CFinishHeader &h) } #endif -HRESULT COutArchive::Create(ISequentialOutStream *stream, bool endMarker) +HRESULT COutArchive::Create_and_WriteStartPrefix(ISequentialOutStream *stream /* , bool endMarker */) { Close(); - #ifdef _7Z_VOL + #ifdef Z7_7Z_VOL // endMarker = false; _endMarker = endMarker; #endif SeqStream = stream; - if (!endMarker) + // if (!endMarker) { SeqStream.QueryInterface(IID_IOutStream, &Stream); if (!Stream) @@ -90,8 +90,13 @@ HRESULT COutArchive::Create(ISequentialOutStream *stream, bool endMarker) return E_NOTIMPL; // endMarker = true; } + RINOK(Stream->Seek(0, STREAM_SEEK_CUR, &_signatureHeaderPos)) + Byte buf[32]; + FillSignature(buf); + memset(&buf[8], 0, 32 - 8); + return WriteDirect(buf, sizeof(buf)); } - #ifdef _7Z_VOL + #ifdef Z7_7Z_VOL if (endMarker) { /* @@ -100,17 +105,10 @@ HRESULT COutArchive::Create(ISequentialOutStream *stream, bool endMarker) sh.NextHeaderSize = (UInt32)(Int32)-1; sh.NextHeaderCRC = 0; WriteStartHeader(sh); + return S_OK; */ } - else #endif - { - if (!Stream) - return E_FAIL; - RINOK(WriteSignature()); - RINOK(Stream->Seek(0, STREAM_SEEK_CUR, &_prefixHeaderPos)); - } - return S_OK; } void COutArchive::Close() @@ -119,17 +117,6 @@ void COutArchive::Close() Stream.Release(); } -HRESULT COutArchive::SkipPrefixArchiveHeader() -{ - #ifdef _7Z_VOL - if (_endMarker) - return S_OK; - #endif - Byte buf[24]; - memset(buf, 0, 24); - return WriteDirect(buf, 24); -} - UInt64 COutArchive::GetPos() const { if (_countMode) @@ -196,7 +183,7 @@ void COutArchive::WriteNumber(UInt64 value) break; } firstByte |= mask; - mask >>= 1; + mask = (Byte)(mask >> 1); } WriteByte(firstByte); for (; i > 0; i--) @@ -206,16 +193,16 @@ void COutArchive::WriteNumber(UInt64 value) } } -static UInt32 GetBigNumberSize(UInt64 value) +static unsigned GetBigNumberSize(UInt64 value) { - int i; + unsigned i; for (i = 1; i < 9; i++) if (value < (((UInt64)1 << (i * 7)))) break; return i; } -#ifdef _7Z_VOL +#ifdef Z7_7Z_VOL UInt32 COutArchive::GetVolHeadersSize(UInt64 dataSize, int nameLength, bool props) { UInt32 result = GetBigNumberSize(dataSize) * 2 + 41; @@ -264,18 +251,18 @@ void COutArchive::WriteFolder(const CFolder &folder) for (idSize = 1; idSize < sizeof(id); idSize++) if ((id >> (8 * idSize)) == 0) break; - idSize &= 0xF; + // idSize &= 0xF; // idSize is smaller than 16 already Byte temp[16]; for (unsigned t = idSize; t != 0; t--, id >>= 8) temp[t] = (Byte)(id & 0xFF); - Byte b = (Byte)(idSize); - bool isComplex = !coder.IsSimpleCoder(); + unsigned b = idSize; + const bool isComplex = !coder.IsSimpleCoder(); b |= (isComplex ? 0x10 : 0); - size_t propsSize = coder.Props.Size(); + const size_t propsSize = coder.Props.Size(); b |= ((propsSize != 0) ? 0x20 : 0); - temp[0] = b; + temp[0] = (Byte)b; WriteBytes(temp, idSize + 1); if (isComplex) { @@ -309,7 +296,7 @@ void COutArchive::WriteBoolVector(const CBoolVector &boolVector) { if (boolVector[i]) b |= mask; - mask >>= 1; + mask = (Byte)(mask >> 1); if (mask == 0) { WriteByte(b); @@ -330,13 +317,11 @@ void COutArchive::WritePropBoolVector(Byte id, const CBoolVector &boolVector) WriteBoolVector(boolVector); } +unsigned BoolVector_CountSum(const CBoolVector &v); + void COutArchive::WriteHashDigests(const CUInt32DefVector &digests) { - unsigned numDefined = 0; - unsigned i; - for (i = 0; i < digests.Defs.Size(); i++) - if (digests.Defs[i]) - numDefined++; + const unsigned numDefined = BoolVector_CountSum(digests.Defs); if (numDefined == 0) return; @@ -348,7 +333,8 @@ void COutArchive::WriteHashDigests(const CUInt32DefVector &digests) WriteByte(0); WriteBoolVector(digests.Defs); } - for (i = 0; i < digests.Defs.Size(); i++) + + for (unsigned i = 0; i < digests.Defs.Size(); i++) if (digests.Defs[i]) WriteUInt32(digests.Vals[i]); } @@ -453,10 +439,12 @@ void COutArchive::WriteSubStreamsInfo(const CObjectVector<CFolder> &folders, // 7-Zip 4.50 - 4.58 contain BUG, so they do not support .7z archives with Unknown field. -void COutArchive::SkipAlign(unsigned pos, unsigned alignSize) +void COutArchive::SkipToAligned(unsigned pos, unsigned alignShifts) { if (!_useAlign) return; + + const unsigned alignSize = (unsigned)1 << alignShifts; pos += (unsigned)GetPos(); pos &= (alignSize - 1); if (pos == 0) @@ -471,11 +459,11 @@ void COutArchive::SkipAlign(unsigned pos, unsigned alignSize) WriteByte(0); } -void COutArchive::WriteAlignedBoolHeader(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSize) +void COutArchive::WriteAlignedBools(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSizeShifts) { const unsigned bvSize = (numDefined == v.Size()) ? 0 : Bv_GetSizeInBytes(v); - const UInt64 dataSize = (UInt64)numDefined * itemSize + bvSize + 2; - SkipAlign(3 + (unsigned)bvSize + (unsigned)GetBigNumberSize(dataSize), itemSize); + const UInt64 dataSize = ((UInt64)numDefined << itemSizeShifts) + bvSize + 2; + SkipToAligned(3 + bvSize + GetBigNumberSize(dataSize), itemSizeShifts); WriteByte(type); WriteNumber(dataSize); @@ -486,24 +474,18 @@ void COutArchive::WriteAlignedBoolHeader(const CBoolVector &v, unsigned numDefin WriteByte(0); WriteBoolVector(v); } - WriteByte(0); + WriteByte(0); // 0 means no switching to external stream } void COutArchive::WriteUInt64DefVector(const CUInt64DefVector &v, Byte type) { - unsigned numDefined = 0; - - unsigned i; - for (i = 0; i < v.Defs.Size(); i++) - if (v.Defs[i]) - numDefined++; - + const unsigned numDefined = BoolVector_CountSum(v.Defs); if (numDefined == 0) return; - WriteAlignedBoolHeader(v.Defs, numDefined, type, 8); + WriteAlignedBools(v.Defs, numDefined, type, 3); - for (i = 0; i < v.Defs.Size(); i++) + for (unsigned i = 0; i < v.Defs.Size(); i++) if (v.Defs[i]) WriteUInt64(v.Vals[i]); } @@ -519,14 +501,20 @@ HRESULT COutArchive::EncodeStream( outFolders.FolderUnpackCRCs.Defs.Add(true); outFolders.FolderUnpackCRCs.Vals.Add(CrcCalc(data, data.Size())); // outFolders.NumUnpackStreamsVector.Add(1); - UInt64 dataSize64 = data.Size(); - UInt64 unpackSize; - RINOK(encoder.Encode( + const UInt64 dataSize64 = data.Size(); + const UInt64 expectSize = data.Size(); + RINOK(encoder.Encode1( EXTERNAL_CODECS_LOC_VARS stream, // NULL, - &dataSize64, - folders.AddNew(), outFolders.CoderUnpackSizes, unpackSize, SeqStream, packSizes, NULL)) + &dataSize64, // inSizeForReduce + expectSize, + folders.AddNew(), + // outFolders.CoderUnpackSizes, unpackSize, + SeqStream, packSizes, NULL)) + if (!streamSpec->WasFinished()) + return E_FAIL; + encoder.Encode_Post(dataSize64, outFolders.CoderUnpackSizes); return S_OK; } @@ -550,7 +538,39 @@ void COutArchive::WriteHeader( WriteByte(NID::kHeader); - // Archive Properties + /* + { + // It's example for per archive properies writing + + WriteByte(NID::kArchiveProperties); + + // you must use random 40-bit number that will identify you + // then you can use same kDeveloperID for any properties and methods + const UInt64 kDeveloperID = 0x123456789A; // change that value to real random 40-bit number + + #define GENERATE_7Z_ID(developerID, subID) (((UInt64)0x3F << 56) | ((UInt64)developerID << 16) | subID) + + { + const UInt64 kSubID = 0x1; // you can use small number for subID + const UInt64 kID = GENERATE_7Z_ID(kDeveloperID, kSubID); + WriteNumber(kID); + const unsigned kPropsSize = 3; // it's example size + WriteNumber(kPropsSize); + for (unsigned i = 0; i < kPropsSize; i++) + WriteByte((Byte)(i & 0xFF)); + } + { + const UInt64 kSubID = 0x2; // you can use small number for subID + const UInt64 kID = GENERATE_7Z_ID(kDeveloperID, kSubID); + WriteNumber(kID); + const unsigned kPropsSize = 5; // it's example size + WriteNumber(kPropsSize); + for (unsigned i = 0; i < kPropsSize; i++) + WriteByte((Byte)(i + 16)); + } + WriteByte(NID::kEnd); + } + */ if (db.Folders.Size() > 0) { @@ -642,13 +662,21 @@ void COutArchive::WriteHeader( const UString &name = db.Names[i]; if (!name.IsEmpty()) numDefined++; - namesDataSize += (name.Len() + 1) * 2; + const size_t numUtfChars = + /* + #if WCHAR_MAX > 0xffff + Get_Num_Utf16_chars_from_wchar_string(name.Ptr()); + #else + */ + name.Len(); + // #endif + namesDataSize += (numUtfChars + 1) * 2; } if (numDefined > 0) { namesDataSize++; - SkipAlign(2 + GetBigNumberSize(namesDataSize), 16); + SkipToAligned(2 + GetBigNumberSize(namesDataSize), 4); WriteByte(NID::kName); WriteNumber(namesDataSize); @@ -659,6 +687,25 @@ void COutArchive::WriteHeader( for (unsigned t = 0; t <= name.Len(); t++) { wchar_t c = name[t]; + + /* + #if WCHAR_MAX > 0xffff + if (c >= 0x10000) + { + c -= 0x10000; + if (c < (1 << 20)) + { + unsigned c0 = 0xd800 + ((c >> 10) & 0x3FF); + WriteByte((Byte)c0); + WriteByte((Byte)(c0 >> 8)); + c = 0xdc00 + (c & 0x3FF); + } + else + c = '_'; // we change character unsupported by UTF16 + } + #endif + */ + WriteByte((Byte)c); WriteByte((Byte)(c >> 8)); } @@ -673,28 +720,15 @@ void COutArchive::WriteHeader( { /* ---------- Write Attrib ---------- */ - CBoolVector boolVector; - boolVector.ClearAndSetSize(db.Files.Size()); - unsigned numDefined = 0; - - { - FOR_VECTOR (i, db.Files) - { - bool defined = db.Files[i].AttribDefined; - boolVector[i] = defined; - if (defined) - numDefined++; - } - } + const unsigned numDefined = BoolVector_CountSum(db.Attrib.Defs); if (numDefined != 0) { - WriteAlignedBoolHeader(boolVector, numDefined, NID::kWinAttrib, 4); - FOR_VECTOR (i, db.Files) + WriteAlignedBools(db.Attrib.Defs, numDefined, NID::kWinAttrib, 2); + FOR_VECTOR (i, db.Attrib.Defs) { - const CFileItem &file = db.Files[i]; - if (file.AttribDefined) - WriteUInt32(file.Attrib); + if (db.Attrib.Defs[i]) + WriteUInt32(db.Attrib.Vals[i]); } } } @@ -702,18 +736,8 @@ void COutArchive::WriteHeader( /* { // ---------- Write IsAux ---------- - unsigned numAux = 0; - const CBoolVector &isAux = db.IsAux; - for (i = 0; i < isAux.Size(); i++) - if (isAux[i]) - numAux++; - if (numAux > 0) - { - const unsigned bvSize = Bv_GetSizeInBytes(isAux); - WriteByte(NID::kIsAux); - WriteNumber(bvSize); - WriteBoolVector(isAux); - } + if (BoolVector_CountSum(db.IsAux) != 0) + WritePropBoolVector(NID::kIsAux, db.IsAux); } { @@ -734,10 +758,10 @@ void COutArchive::WriteHeader( } if (numParentLinks > 0) { - // WriteAlignedBoolHeader(boolVector, numDefined, NID::kParent, 4); + // WriteAlignedBools(boolVector, numDefined, NID::kParent, 2); const unsigned bvSize = (numIsDir == boolVector.Size()) ? 0 : Bv_GetSizeInBytes(boolVector); const UInt64 dataSize = (UInt64)db.Files.Size() * 4 + bvSize + 1; - SkipAlign(2 + (unsigned)bvSize + (unsigned)GetBigNumberSize(dataSize), 4); + SkipToAligned(2 + (unsigned)bvSize + (unsigned)GetBigNumberSize(dataSize), 2); WriteByte(NID::kParent); WriteNumber(dataSize); @@ -765,7 +789,7 @@ void COutArchive::WriteHeader( // secureDataSize += db.SecureIDs.Size() * 4; for (i = 0; i < db.SecureIDs.Size(); i++) secureDataSize += GetBigNumberSize(db.SecureIDs[i]); - SkipAlign(2 + GetBigNumberSize(secureDataSize), 4); + SkipToAligned(2 + GetBigNumberSize(secureDataSize), 2); WriteByte(NID::kNtSecure); WriteNumber(secureDataSize); WriteByte(0); @@ -801,15 +825,15 @@ HRESULT COutArchive::WriteDatabase( { headerSize = 0; headerOffset = 0; - headerCRC = CrcCalc(0, 0); + headerCRC = CrcCalc(NULL, 0); } else { bool encodeHeaders = false; - if (options != 0) + if (options) if (options->IsEmpty()) - options = 0; - if (options != 0) + options = NULL; + if (options) if (options->PasswordIsDefined || headerOptions.CompressMainHeader) encodeHeaders = true; @@ -844,7 +868,7 @@ HRESULT COutArchive::WriteDatabase( RINOK(EncodeStream( EXTERNAL_CODECS_LOC_VARS encoder, buf, - packSizes, folders, outFolders)); + packSizes, folders, outFolders)) _writeToStream = true; @@ -858,11 +882,11 @@ HRESULT COutArchive::WriteDatabase( FOR_VECTOR (i, packSizes) headerOffset += packSizes[i]; } - RINOK(_outByte.Flush()); + RINOK(_outByte.Flush()) headerCRC = CRC_GET_DIGEST(_crc); headerSize = _outByte.GetProcessedSize(); } - #ifdef _7Z_VOL + #ifdef Z7_7Z_VOL if (_endMarker) { CFinishHeader h; @@ -878,14 +902,28 @@ HRESULT COutArchive::WriteDatabase( } else #endif + if (Stream) { CStartHeader h; h.NextHeaderSize = headerSize; h.NextHeaderCRC = headerCRC; h.NextHeaderOffset = headerOffset; - RINOK(Stream->Seek(_prefixHeaderPos, STREAM_SEEK_SET, NULL)); + RINOK(Stream->Seek((Int64)_signatureHeaderPos, STREAM_SEEK_SET, NULL)) return WriteStartHeader(h); } + return S_OK; +} + +void CUInt32DefVector::SetItem(unsigned index, bool defined, UInt32 value) +{ + while (index >= Defs.Size()) + Defs.Add(false); + Defs[index] = defined; + if (!defined) + return; + while (index >= Vals.Size()) + Vals.Add(0); + Vals[index] = value; } void CUInt64DefVector::SetItem(unsigned index, bool defined, UInt64 value) @@ -907,6 +945,7 @@ void CArchiveDatabaseOut::AddFile(const CFileItem &file, const CFileItem2 &file2 ATime.SetItem(index, file2.ATimeDefined, file2.ATime); MTime.SetItem(index, file2.MTimeDefined, file2.MTime); StartPos.SetItem(index, file2.StartPosDefined, file2.StartPos); + Attrib.SetItem(index, file2.AttribDefined, file2.Attrib); SetItem_Anti(index, file2.IsAnti); // SetItem_Aux(index, file2.IsAux); Names.Add(name); diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zOut.h b/3rdparty/lzma/CPP/7zip/Archive/7z/7zOut.h index 6c902668939..940cafcdfb4 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zOut.h +++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zOut.h @@ -1,7 +1,7 @@ // 7zOut.h -#ifndef __7Z_OUT_H -#define __7Z_OUT_H +#ifndef ZIP7_INC_7Z_OUT_H +#define ZIP7_INC_7Z_OUT_H #include "7zCompressionMode.h" #include "7zEncode.h" @@ -14,6 +14,8 @@ namespace NArchive { namespace N7z { +const unsigned k_StartHeadersRewriteSize = 32; + class CWriteBufferLoc { Byte *_data; @@ -45,6 +47,7 @@ public: size_t GetPos() const { return _pos; } }; + struct CHeaderOptions { bool CompressMainHeader; @@ -71,24 +74,31 @@ struct CFileItem2 UInt64 ATime; UInt64 MTime; UInt64 StartPos; + UInt32 Attrib; + bool CTimeDefined; bool ATimeDefined; bool MTimeDefined; bool StartPosDefined; + bool AttribDefined; bool IsAnti; // bool IsAux; + /* void Init() { CTimeDefined = false; ATimeDefined = false; MTimeDefined = false; StartPosDefined = false; + AttribDefined = false; IsAnti = false; // IsAux = false; } + */ }; + struct COutFolders { CUInt32DefVector FolderUnpackCRCs; // Now we use it for headers only. @@ -111,6 +121,7 @@ struct COutFolders } }; + struct CArchiveDatabaseOut: public COutFolders { CRecordVector<UInt64> PackSizes; @@ -123,10 +134,11 @@ struct CArchiveDatabaseOut: public COutFolders CUInt64DefVector ATime; CUInt64DefVector MTime; CUInt64DefVector StartPos; - CRecordVector<bool> IsAnti; + CUInt32DefVector Attrib; + CBoolVector IsAnti; /* - CRecordVector<bool> IsAux; + CBoolVector IsAux; CByteBuffer SecureBuf; CRecordVector<UInt32> SecureSizes; @@ -154,6 +166,7 @@ struct CArchiveDatabaseOut: public COutFolders ATime.Clear(); MTime.Clear(); StartPos.Clear(); + Attrib.Clear(); IsAnti.Clear(); /* @@ -176,6 +189,7 @@ struct CArchiveDatabaseOut: public COutFolders ATime.ReserveDown(); MTime.ReserveDown(); StartPos.ReserveDown(); + Attrib.ReserveDown(); IsAnti.ReserveDown(); /* @@ -196,11 +210,12 @@ struct CArchiveDatabaseOut: public COutFolders { unsigned size = Files.Size(); return ( - CTime.CheckSize(size) && - ATime.CheckSize(size) && - MTime.CheckSize(size) && - StartPos.CheckSize(size) && - (size == IsAnti.Size() || IsAnti.Size() == 0)); + CTime.CheckSize(size) + && ATime.CheckSize(size) + && MTime.CheckSize(size) + && StartPos.CheckSize(size) + && Attrib.CheckSize(size) + && (size == IsAnti.Size() || IsAnti.Size() == 0)); } bool IsItemAnti(unsigned index) const { return (index < IsAnti.Size() && IsAnti[index]); } @@ -224,10 +239,9 @@ struct CArchiveDatabaseOut: public COutFolders void AddFile(const CFileItem &file, const CFileItem2 &file2, const UString &name); }; + class COutArchive { - UInt64 _prefixHeaderPos; - HRESULT WriteDirect(const void *data, UInt32 size) { return WriteStream(SeqStream, data, size); } UInt64 GetPos() const; @@ -261,8 +275,8 @@ class COutArchive const CRecordVector<UInt64> &unpackSizes, const CUInt32DefVector &digests); - void SkipAlign(unsigned pos, unsigned alignSize); - void WriteAlignedBoolHeader(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSize); + void SkipToAligned(unsigned pos, unsigned alignShifts); + void WriteAlignedBools(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSizeShifts); void WriteUInt64DefVector(const CUInt64DefVector &v, Byte type); HRESULT EncodeStream( @@ -276,44 +290,39 @@ class COutArchive bool _countMode; bool _writeToStream; - size_t _countSize; - UInt32 _crc; - COutBuffer _outByte; - CWriteBufferLoc _outByte2; - - #ifdef _7Z_VOL + bool _useAlign; + #ifdef Z7_7Z_VOL bool _endMarker; #endif + UInt32 _crc; + size_t _countSize; + CWriteBufferLoc _outByte2; + COutBuffer _outByte; + UInt64 _signatureHeaderPos; + CMyComPtr<IOutStream> Stream; - bool _useAlign; - - HRESULT WriteSignature(); - #ifdef _7Z_VOL + #ifdef Z7_7Z_VOL HRESULT WriteFinishSignature(); - #endif - HRESULT WriteStartHeader(const CStartHeader &h); - #ifdef _7Z_VOL HRESULT WriteFinishHeader(const CFinishHeader &h); #endif - CMyComPtr<IOutStream> Stream; + HRESULT WriteStartHeader(const CStartHeader &h); + public: + CMyComPtr<ISequentialOutStream> SeqStream; COutArchive() { _outByte.Create(1 << 16); } - CMyComPtr<ISequentialOutStream> SeqStream; - HRESULT Create(ISequentialOutStream *stream, bool endMarker); + HRESULT Create_and_WriteStartPrefix(ISequentialOutStream *stream /* , bool endMarker */); void Close(); - HRESULT SkipPrefixArchiveHeader(); HRESULT WriteDatabase( DECL_EXTERNAL_CODECS_LOC_VARS const CArchiveDatabaseOut &db, const CCompressionMethodMode *options, const CHeaderOptions &headerOptions); - #ifdef _7Z_VOL + #ifdef Z7_7Z_VOL static UInt32 GetVolHeadersSize(UInt64 dataSize, int nameLength = 0, bool props = false); static UInt64 GetVolPureSize(UInt64 volSize, int nameLength = 0, bool props = false); #endif - }; }} diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zProperties.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zProperties.cpp index 4cb5a5e6469..d3b3cbe57dc 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zProperties.cpp +++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zProperties.cpp @@ -2,56 +2,63 @@ #include "StdAfx.h" -#include "7zProperties.h" -#include "7zHeader.h" #include "7zHandler.h" - -// #define _MULTI_PACK +#include "7zProperties.h" namespace NArchive { namespace N7z { struct CPropMap { - UInt32 FilePropID; - CStatProp StatProp; + Byte FilePropID; + // CStatProp StatProp; + VARTYPE vt; + UInt32 StatPropID; }; +// #define STAT_PROP(name, id, vt) { name, id, vt } +#define STAT_PROP(name, id, vt) vt, id + +#define STAT_PROP2(id, vt) STAT_PROP(NULL, id, vt) + +#define k_7z_id_Encrypted 97 +#define k_7z_id_Method 98 +#define k_7z_id_Block 99 + static const CPropMap kPropMap[] = { - { NID::kName, { NULL, kpidPath, VT_BSTR } }, - { NID::kSize, { NULL, kpidSize, VT_UI8 } }, - { NID::kPackInfo, { NULL, kpidPackSize, VT_UI8 } }, + { NID::kName, STAT_PROP2(kpidPath, VT_BSTR) }, + { NID::kSize, STAT_PROP2(kpidSize, VT_UI8) }, + { NID::kPackInfo, STAT_PROP2(kpidPackSize, VT_UI8) }, - #ifdef _MULTI_PACK - { 100, { "Pack0", kpidPackedSize0, VT_UI8 } }, - { 101, { "Pack1", kpidPackedSize1, VT_UI8 } }, - { 102, { "Pack2", kpidPackedSize2, VT_UI8 } }, - { 103, { "Pack3", kpidPackedSize3, VT_UI8 } }, - { 104, { "Pack4", kpidPackedSize4, VT_UI8 } }, + #ifdef Z7_7Z_SHOW_PACK_STREAMS_SIZES +#define k_7z_id_PackedSize0 100 + { k_7z_id_PackedSize0 + 0, STAT_PROP("Pack0", kpidPackedSize0, VT_UI8) }, + { k_7z_id_PackedSize0 + 1, STAT_PROP("Pack1", kpidPackedSize1, VT_UI8) }, + { k_7z_id_PackedSize0 + 2, STAT_PROP("Pack2", kpidPackedSize2, VT_UI8) }, + { k_7z_id_PackedSize0 + 3, STAT_PROP("Pack3", kpidPackedSize3, VT_UI8) }, + { k_7z_id_PackedSize0 + 4, STAT_PROP("Pack4", kpidPackedSize4, VT_UI8) }, #endif - { NID::kCTime, { NULL, kpidCTime, VT_FILETIME } }, - { NID::kMTime, { NULL, kpidMTime, VT_FILETIME } }, - { NID::kATime, { NULL, kpidATime, VT_FILETIME } }, - { NID::kWinAttrib, { NULL, kpidAttrib, VT_UI4 } }, - { NID::kStartPos, { NULL, kpidPosition, VT_UI8 } }, + { NID::kCTime, STAT_PROP2(kpidCTime, VT_FILETIME) }, + { NID::kMTime, STAT_PROP2(kpidMTime, VT_FILETIME) }, + { NID::kATime, STAT_PROP2(kpidATime, VT_FILETIME) }, + { NID::kWinAttrib, STAT_PROP2(kpidAttrib, VT_UI4) }, + { NID::kStartPos, STAT_PROP2(kpidPosition, VT_UI8) }, - { NID::kCRC, { NULL, kpidCRC, VT_UI4 } }, - -// { NID::kIsAux, { NULL, kpidIsAux, VT_BOOL } }, - { NID::kAnti, { NULL, kpidIsAnti, VT_BOOL } } - - #ifndef _SFX - , - { 97, { NULL, kpidEncrypted, VT_BOOL } }, - { 98, { NULL, kpidMethod, VT_BSTR } }, - { 99, { NULL, kpidBlock, VT_UI4 } } + { NID::kCRC, STAT_PROP2(kpidCRC, VT_UI4) }, + // { NID::kIsAux, STAT_PROP2(kpidIsAux, VT_BOOL) }, + { NID::kAnti, STAT_PROP2(kpidIsAnti, VT_BOOL) } + + #ifndef Z7_SFX + , { k_7z_id_Encrypted, STAT_PROP2(kpidEncrypted, VT_BOOL) } + , { k_7z_id_Method, STAT_PROP2(kpidMethod, VT_BSTR) } + , { k_7z_id_Block, STAT_PROP2(kpidBlock, VT_UI4) } #endif }; static void CopyOneItem(CRecordVector<UInt64> &src, - CRecordVector<UInt64> &dest, UInt32 item) + CRecordVector<UInt64> &dest, const UInt32 item) { FOR_VECTOR (i, src) if (src[i] == item) @@ -62,7 +69,7 @@ static void CopyOneItem(CRecordVector<UInt64> &src, } } -static void RemoveOneItem(CRecordVector<UInt64> &src, UInt32 item) +static void RemoveOneItem(CRecordVector<UInt64> &src, const UInt32 item) { FOR_VECTOR (i, src) if (src[i] == item) @@ -72,7 +79,7 @@ static void RemoveOneItem(CRecordVector<UInt64> &src, UInt32 item) } } -static void InsertToHead(CRecordVector<UInt64> &dest, UInt32 item) +static void InsertToHead(CRecordVector<UInt64> &dest, const UInt32 item) { FOR_VECTOR (i, dest) if (dest[i] == item) @@ -89,7 +96,7 @@ void CHandler::FillPopIDs() { _fileInfoPopIDs.Clear(); - #ifdef _7Z_VOL + #ifdef Z7_7Z_VOL if (_volumes.Size() < 1) return; const CVolume &volume = _volumes.Front(); @@ -105,34 +112,31 @@ void CHandler::FillPopIDs() RemoveOneItem(fileInfoPopIDs, NID::kNtSecure); */ - COPY_ONE_ITEM(kName); - COPY_ONE_ITEM(kAnti); - COPY_ONE_ITEM(kSize); - COPY_ONE_ITEM(kPackInfo); - COPY_ONE_ITEM(kCTime); - COPY_ONE_ITEM(kMTime); - COPY_ONE_ITEM(kATime); - COPY_ONE_ITEM(kWinAttrib); - COPY_ONE_ITEM(kCRC); - COPY_ONE_ITEM(kComment); + COPY_ONE_ITEM(kName) + COPY_ONE_ITEM(kAnti) + COPY_ONE_ITEM(kSize) + COPY_ONE_ITEM(kPackInfo) + COPY_ONE_ITEM(kCTime) + COPY_ONE_ITEM(kMTime) + COPY_ONE_ITEM(kATime) + COPY_ONE_ITEM(kWinAttrib) + COPY_ONE_ITEM(kCRC) + COPY_ONE_ITEM(kComment) _fileInfoPopIDs += fileInfoPopIDs; - #ifndef _SFX - _fileInfoPopIDs.Add(97); - _fileInfoPopIDs.Add(98); - _fileInfoPopIDs.Add(99); + #ifndef Z7_SFX + _fileInfoPopIDs.Add(k_7z_id_Encrypted); + _fileInfoPopIDs.Add(k_7z_id_Method); + _fileInfoPopIDs.Add(k_7z_id_Block); #endif - #ifdef _MULTI_PACK - _fileInfoPopIDs.Add(100); - _fileInfoPopIDs.Add(101); - _fileInfoPopIDs.Add(102); - _fileInfoPopIDs.Add(103); - _fileInfoPopIDs.Add(104); + #ifdef Z7_7Z_SHOW_PACK_STREAMS_SIZES + for (unsigned i = 0; i < 5; i++) + _fileInfoPopIDs.Add(k_7z_id_PackedSize0 + i); #endif - #ifndef _SFX + #ifndef Z7_SFX InsertToHead(_fileInfoPopIDs, NID::kMTime); InsertToHead(_fileInfoPopIDs, NID::kPackInfo); InsertToHead(_fileInfoPopIDs, NID::kSize); @@ -140,25 +144,29 @@ void CHandler::FillPopIDs() #endif } -STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps) +Z7_COM7F_IMF(CHandler::GetNumberOfProperties(UInt32 *numProps)) { *numProps = _fileInfoPopIDs.Size(); return S_OK; } -STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) +Z7_COM7F_IMF(CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)) { if (index >= _fileInfoPopIDs.Size()) return E_INVALIDARG; - UInt64 id = _fileInfoPopIDs[index]; - for (unsigned i = 0; i < ARRAY_SIZE(kPropMap); i++) + const UInt64 id = _fileInfoPopIDs[index]; + for (unsigned i = 0; i < Z7_ARRAY_SIZE(kPropMap); i++) { const CPropMap &pr = kPropMap[i]; if (pr.FilePropID == id) { + *propID = pr.StatPropID; + *varType = pr.vt; + /* const CStatProp &st = pr.StatProp; *propID = st.PropID; *varType = st.vt; + */ /* if (st.lpwstrName) *name = ::SysAllocString(st.lpwstrName); diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zProperties.h b/3rdparty/lzma/CPP/7zip/Archive/7z/7zProperties.h index 66181795422..091c39b4037 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zProperties.h +++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zProperties.h @@ -1,13 +1,16 @@ // 7zProperties.h -#ifndef __7Z_PROPERTIES_H -#define __7Z_PROPERTIES_H +#ifndef ZIP7_INC_7Z_PROPERTIES_H +#define ZIP7_INC_7Z_PROPERTIES_H #include "../../PropID.h" namespace NArchive { namespace N7z { +// #define Z7_7Z_SHOW_PACK_STREAMS_SIZES // for debug + +#ifdef Z7_7Z_SHOW_PACK_STREAMS_SIZES enum { kpidPackedSize0 = kpidUserDefined, @@ -16,6 +19,7 @@ enum kpidPackedSize3, kpidPackedSize4 }; +#endif }} diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zRegister.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zRegister.cpp index 389b54074e4..1f11079e626 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zRegister.cpp +++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zRegister.cpp @@ -15,7 +15,13 @@ REGISTER_ARC_IO_DECREMENT_SIG( "7z", "7z", NULL, 7, k_Signature_Dec, 0, - NArcInfoFlags::kFindSignature, - NULL); + NArcInfoFlags::kFindSignature + | NArcInfoFlags::kCTime + | NArcInfoFlags::kATime + | NArcInfoFlags::kMTime + | NArcInfoFlags::kMTime_Default + , TIME_PREC_TO_ARC_FLAGS_MASK(NFileTimeType::kWindows) + | TIME_PREC_TO_ARC_FLAGS_TIME_DEFAULT(NFileTimeType::kWindows) + , NULL) }} diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zSpecStream.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zSpecStream.cpp index 8e45d98756c..8b531bc7c9f 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zSpecStream.cpp +++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zSpecStream.cpp @@ -4,19 +4,28 @@ #include "7zSpecStream.h" -STDMETHODIMP CSequentialInStreamSizeCount2::Read(void *data, UInt32 size, UInt32 *processedSize) +/* +Z7_COM7F_IMF(CSequentialInStreamSizeCount2::Read(void *data, UInt32 size, UInt32 *processedSize)) { UInt32 realProcessedSize; - HRESULT result = _stream->Read(data, size, &realProcessedSize); + const HRESULT result = _stream->Read(data, size, &realProcessedSize); _size += realProcessedSize; if (processedSize) *processedSize = realProcessedSize; return result; } -STDMETHODIMP CSequentialInStreamSizeCount2::GetSubStreamSize(UInt64 subStream, UInt64 *value) +Z7_COM7F_IMF(CSequentialInStreamSizeCount2::GetSubStreamSize(UInt64 subStream, UInt64 *value)) { if (!_getSubStreamSize) return E_NOTIMPL; return _getSubStreamSize->GetSubStreamSize(subStream, value); } + +Z7_COM7F_IMF(CSequentialInStreamSizeCount2::GetNextInSubStream(UInt64 *streamIndexRes, ISequentialInStream **stream)) +{ + if (!_compressGetSubStreamSize) + return E_NOTIMPL; + return _compressGetSubStreamSize->GetNextInSubStream(streamIndexRes, stream); +} +*/ diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zSpecStream.h b/3rdparty/lzma/CPP/7zip/Archive/7z/7zSpecStream.h index 21155069f2d..78f631e432a 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zSpecStream.h +++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zSpecStream.h @@ -1,35 +1,49 @@ // 7zSpecStream.h -#ifndef __7Z_SPEC_STREAM_H -#define __7Z_SPEC_STREAM_H +#ifndef ZIP7_INC_7Z_SPEC_STREAM_H +#define ZIP7_INC_7Z_SPEC_STREAM_H #include "../../../Common/MyCom.h" #include "../../ICoder.h" -class CSequentialInStreamSizeCount2: +/* +#define Z7_COM_QI_ENTRY_AG_2(i, sub0, sub) else if (iid == IID_ ## i) \ + { if (!sub) RINOK(sub0->QueryInterface(IID_ ## i, (void **)&sub)) \ + { i *ti = this; *outObject = ti; } } + +class CSequentialInStreamSizeCount2 Z7_final: public ISequentialInStream, public ICompressGetSubStreamSize, + public ICompressInSubStreams, public CMyUnknownImp { + Z7_COM_QI_BEGIN2(ISequentialInStream) + Z7_COM_QI_ENTRY(ICompressGetSubStreamSize) + Z7_COM_QI_ENTRY_AG_2(ISequentialInStream, _stream, _compressGetSubStreamSize) + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(ISequentialInStream) + Z7_IFACE_COM7_IMP(ICompressGetSubStreamSize) + Z7_IFACE_COM7_IMP(ICompressInSubStreams) + CMyComPtr<ISequentialInStream> _stream; CMyComPtr<ICompressGetSubStreamSize> _getSubStreamSize; + CMyComPtr<ICompressInSubStreams> _compressGetSubStreamSize; UInt64 _size; public: void Init(ISequentialInStream *stream) { _size = 0; _getSubStreamSize.Release(); + _compressGetSubStreamSize.Release(); _stream = stream; _stream.QueryInterface(IID_ICompressGetSubStreamSize, &_getSubStreamSize); + _stream.QueryInterface(IID_ICompressInSubStreams, &_compressGetSubStreamSize); } UInt64 GetSize() const { return _size; } - - MY_UNKNOWN_IMP2(ISequentialInStream, ICompressGetSubStreamSize) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - - STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value); }; +*/ #endif diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zUpdate.cpp b/3rdparty/lzma/CPP/7zip/Archive/7z/7zUpdate.cpp index 68e57f09d5f..4e9ea5d4868 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zUpdate.cpp +++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zUpdate.cpp @@ -4,6 +4,8 @@ #include "../../../../C/CpuArch.h" +#include "../../../Common/MyLinux.h" +#include "../../../Common/StringToInt.h" #include "../../../Common/Wildcard.h" #include "../../Common/CreateCoder.h" @@ -24,24 +26,43 @@ namespace NArchive { namespace N7z { - #define k_X86 k_BCJ struct CFilterMode { UInt32 Id; - UInt32 Delta; - - CFilterMode(): Id(0), Delta(0) {} + UInt32 Delta; // required File Size alignment, if Id is not k_Delta. + // (Delta == 0) means unknown alignment + UInt32 Offset; // for k_ARM64 + // UInt32 AlignSizeOpt; // for k_ARM64 + + CFilterMode(): + Id(0), + Delta(0), + Offset(0) + // , AlignSizeOpt(0) + {} + + void ClearFilterMode() + { + Id = 0; + Delta = 0; + Offset = 0; + // AlignSizeOpt = 0; + } + // it sets Delta as Align value, if Id is exe filter + // in another cases it sets Delta = 0, that void SetDelta() { if (Id == k_IA64) Delta = 16; - else if (Id == k_ARM || Id == k_PPC || Id == k_SPARC) + else if (Id == k_ARM64 || Id == k_ARM || Id == k_PPC || Id == k_SPARC) Delta = 4; else if (Id == k_ARMT) Delta = 2; + else if (Id == k_BCJ || Id == k_BCJ2) + Delta = 1; // do we need it? else Delta = 0; } @@ -55,8 +76,8 @@ struct CFilterMode #define PE_SIG 0x00004550 #define PE_OptHeader_Magic_32 0x10B #define PE_OptHeader_Magic_64 0x20B -#define PE_SectHeaderSize 40 -#define PE_SECT_EXECUTE 0x20000000 +// #define PE_SectHeaderSize 40 +// #define PE_SECT_EXECUTE 0x20000000 static int Parse_EXE(const Byte *buf, size_t size, CFilterMode *filterMode) { @@ -78,6 +99,7 @@ static int Parse_EXE(const Byte *buf, size_t size, CFilterMode *filterMode) { case 0x014C: case 0x8664: filterId = k_X86; break; + case 0xAA64: filterId = k_ARM64; break; /* IMAGE_FILE_MACHINE_ARM 0x01C0 // ARM LE @@ -94,6 +116,7 @@ static int Parse_EXE(const Byte *buf, size_t size, CFilterMode *filterMode) default: return 0; } + // const UInt32 numSections = GetUi16(p + 2); optHeaderSize = GetUi16(p + 16); if (optHeaderSize > (1 << 10)) return 0; @@ -109,6 +132,63 @@ static int Parse_EXE(const Byte *buf, size_t size, CFilterMode *filterMode) return 0; } + /* + // Windows exe file sizes are not aligned for 4 KiB. + // So we can't use (CFilterMode::Offset != 0) in solid archives. + // So we just don't set Offset here. +#define NUM_SCAN_SECTIONS_MAX (1 << 6) +#define EXE_SECTION_OFFSET_MAX (1 << 27) +#define EXE_SECTION_SIZE_MIN (1 << 8) +#define EXE_SECTION_SIZE_MAX (1 << 27) +#define PE_SectHeaderSize 40 +#define PE_SECT_EXECUTE 0x20000000 + + if (numSections > NUM_SCAN_SECTIONS_MAX) + return 0; + + p += optHeaderSize; + // UInt32 numExeSections = 0; + // bool execute_finded = false; + // UInt32 sect_va = 0; + // UInt32 sect_size = 0; + // UInt32 sect_offset = 0; + + for (UInt32 i = 0; i < numSections + // && numExeSections < numSectionsMax + ; i++, p += PE_SectHeaderSize) + { + UInt32 characts, rawSize, offset; + if ((UInt32)(p - buf) + PE_SectHeaderSize > size) + return 0; + rawSize = GetUi32(p + 16); + offset = GetUi32(p + 20); + characts = GetUi32(p + 36); + if (rawSize >= EXE_SECTION_SIZE_MIN && + rawSize <= EXE_SECTION_SIZE_MAX && + offset <= EXE_SECTION_OFFSET_MAX && + // offset < limit && + offset > 0) + { + if ((characts & PE_SECT_EXECUTE) != 0) + { + // execute_finded = true; + // sect_va = GetUi32(p + 12); + // sect_size = rawSize; + // sect_offset = offset; + break; + } + } + } + + filterMode->Offset = 0; + if (filterId == k_ARM64) + { + // filterMode->AlignSizeOpt = (1 << 12); + // const UInt32 offs = (sect_va - sect_offset) & 0xFFF; + // if (offs != 0) + // filterMode->Offset = offs; // change it + } + */ filterMode->Id = filterId; return 1; } @@ -124,13 +204,13 @@ static int Parse_EXE(const Byte *buf, size_t size, CFilterMode *filterMode) #define ELF_DATA_2LSB 1 #define ELF_DATA_2MSB 2 -static UInt16 Get16(const Byte *p, Bool be) { if (be) return (UInt16)GetBe16(p); return (UInt16)GetUi16(p); } -static UInt32 Get32(const Byte *p, Bool be) { if (be) return GetBe32(p); return GetUi32(p); } -// static UInt64 Get64(const Byte *p, Bool be) { if (be) return GetBe64(p); return GetUi64(p); } +static UInt16 Get16(const Byte *p, BoolInt be) { if (be) return (UInt16)GetBe16(p); return (UInt16)GetUi16(p); } +static UInt32 Get32(const Byte *p, BoolInt be) { if (be) return GetBe32(p); return GetUi32(p); } +// static UInt64 Get64(const Byte *p, BoolInt be) { if (be) return GetBe64(p); return GetUi64(p); } static int Parse_ELF(const Byte *buf, size_t size, CFilterMode *filterMode) { - Bool /* is32, */ be; + BoolInt /* is32, */ be; UInt32 filterId; if (size < 512 || buf[6] != 1) /* ver */ @@ -164,8 +244,9 @@ static int Parse_ELF(const Byte *buf, size_t size, CFilterMode *filterMode) case 20: case 21: if (!be) return 0; filterId = k_PPC; break; case 40: if ( be) return 0; filterId = k_ARM; break; - - /* Some IA-64 ELF exacutable have size that is not aligned for 16 bytes. + case 183: if (be) return 0; filterId = k_ARM64; break; + + /* Some IA-64 ELF executables have size that is not aligned for 16 bytes. So we don't use IA-64 filter for IA-64 ELF */ // case 50: if ( be) return 0; filterId = k_IA64; break; @@ -192,6 +273,7 @@ static int Parse_ELF(const Byte *buf, size_t size, CFilterMode *filterMode) #define MACH_MACHINE_PPC 18 #define MACH_MACHINE_PPC64 (MACH_ARCH_ABI64 | MACH_MACHINE_PPC) #define MACH_MACHINE_AMD64 (MACH_ARCH_ABI64 | MACH_MACHINE_386) +#define MACH_MACHINE_ARM64 (MACH_ARCH_ABI64 | MACH_MACHINE_ARM) static unsigned Parse_MACH(const Byte *buf, size_t size, CFilterMode *filterMode) { @@ -200,7 +282,7 @@ static unsigned Parse_MACH(const Byte *buf, size_t size, CFilterMode *filterMode if (size < 512) return 0; - Bool /* mode64, */ be; + BoolInt /* mode64, */ be; switch (GetUi32(buf)) { case MACH_SIG_BE_32: /* mode64 = False; */ be = True; break; @@ -218,6 +300,7 @@ static unsigned Parse_MACH(const Byte *buf, size_t size, CFilterMode *filterMode case MACH_MACHINE_SPARC: if (!be) return 0; filterId = k_SPARC; break; case MACH_MACHINE_PPC: case MACH_MACHINE_PPC64: if (!be) return 0; filterId = k_PPC; break; + case MACH_MACHINE_ARM64: if ( be) return 0; filterId = k_ARM64; break; default: return 0; } @@ -239,7 +322,7 @@ static unsigned Parse_MACH(const Byte *buf, size_t size, CFilterMode *filterMode #define RIFF_SIG 0x46464952 -static Bool Parse_WAV(const Byte *buf, size_t size, CFilterMode *filterMode) +static BoolInt Parse_WAV(const Byte *buf, size_t size, CFilterMode *filterMode) { UInt32 subChunkSize, pos; if (size < 0x2C) @@ -254,10 +337,12 @@ static Bool Parse_WAV(const Byte *buf, size_t size, CFilterMode *filterMode) if (subChunkSize < 0x10 || subChunkSize > 0x12 || GetUi16(buf + 0x14) != 1) return False; - unsigned numChannels = GetUi16(buf + 0x16); - unsigned bitsPerSample = GetUi16(buf + 0x22); - - if ((bitsPerSample & 0x7) != 0 || bitsPerSample >= 256 || numChannels >= 256) + const unsigned numChannels = GetUi16(buf + 0x16); + const unsigned bitsPerSample = GetUi16(buf + 0x22); + if ((bitsPerSample & 0x7) != 0) + return False; + const UInt32 delta = (UInt32)numChannels * (bitsPerSample >> 3); + if (delta == 0 || delta > 256) return False; pos = 0x14 + subChunkSize; @@ -271,9 +356,6 @@ static Bool Parse_WAV(const Byte *buf, size_t size, CFilterMode *filterMode) subChunkSize = GetUi32(buf + pos + 4); if (GetUi32(buf + pos) == WAV_SUBCHUNK_data) { - unsigned delta = numChannels * (bitsPerSample >> 3); - if (delta >= 256) - return False; filterMode->Id = k_Delta; filterMode->Delta = delta; return True; @@ -285,10 +367,15 @@ static Bool Parse_WAV(const Byte *buf, size_t size, CFilterMode *filterMode) return False; } -static Bool ParseFile(const Byte *buf, size_t size, CFilterMode *filterMode) + +/* + filterMode->Delta will be set as: + = delta value : [1, 256] : for k_Delta + = 0 for another filters (branch filters) +*/ +static BoolInt ParseFile(const Byte *buf, size_t size, CFilterMode *filterMode) { - filterMode->Id = 0; - filterMode->Delta = 0; + filterMode->ClearFilterMode(); if (Parse_EXE(buf, size, filterMode)) return True; if (Parse_ELF(buf, size, filterMode)) return True; @@ -316,18 +403,44 @@ struct CFilterMode2: public CFilterMode else if (!m.Encrypted) return 1; - if (Id < m.Id) return -1; - if (Id > m.Id) return 1; + const UInt32 id1 = Id; + const UInt32 id2 = m.Id; + /* + // we can change the order to place k_ARM64 files close to another exe files + if (id1 <= k_SPARC && + id2 <= k_SPARC) + { + #define k_ARM64_FOR_SORT 0x3030901 + if (id1 == k_ARM64) id1 = k_ARM64_FOR_SORT; + if (id2 == k_ARM64) id2 = k_ARM64_FOR_SORT; + } + */ + if (id1 < id2) return -1; + if (id1 > id2) return 1; if (Delta < m.Delta) return -1; if (Delta > m.Delta) return 1; + if (Offset < m.Offset) return -1; + if (Offset > m.Offset) return 1; + + /* we don't go here, because GetGroup() + and operator ==(const CFilterMode2 &m) + add only unique CFilterMode2:: { Id, Delta, Offset, Encrypted } items. + */ + /* + if (GroupIndex < m.GroupIndex) return -1; + if (GroupIndex > m.GroupIndex) return 1; + */ return 0; } bool operator ==(const CFilterMode2 &m) const { - return Id == m.Id && Delta == m.Delta && Encrypted == m.Encrypted; + return Id == m.Id + && Delta == m.Delta + && Offset == m.Offset + && Encrypted == m.Encrypted; } }; @@ -368,6 +481,7 @@ static inline bool IsExeFilter(CMethodId m) { switch (m) { + case k_ARM64: case k_BCJ: case k_BCJ2: case k_ARM: @@ -384,8 +498,9 @@ static unsigned Get_FilterGroup_for_Folder( CRecordVector<CFilterMode2> &filters, const CFolderEx &f, bool extractFilter) { CFilterMode2 m; - m.Id = 0; - m.Delta = 0; + // m.Id = 0; + // m.Delta = 0; + // m.Offset = 0; m.Encrypted = f.IsEncrypted(); if (extractFilter) @@ -406,6 +521,9 @@ static unsigned Get_FilterGroup_for_Folder( if (m.Id == k_BCJ2) m.Id = k_BCJ; m.SetDelta(); + if (m.Id == k_ARM64) + if (coder.Props.Size() == 4) + m.Offset = GetUi32(coder.Props); } } @@ -418,15 +536,15 @@ static unsigned Get_FilterGroup_for_Folder( static HRESULT WriteRange(IInStream *inStream, ISequentialOutStream *outStream, UInt64 position, UInt64 size, ICompressProgressInfo *progress) { - RINOK(inStream->Seek(position, STREAM_SEEK_SET, 0)); + RINOK(InStream_SeekSet(inStream, position)) CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr<CLimitedSequentialInStream> inStreamLimited(streamSpec); + CMyComPtr<ISequentialInStream> inStreamLimited(streamSpec); streamSpec->SetStream(inStream); streamSpec->Init(size); NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec; - RINOK(copyCoder->Code(inStreamLimited, outStream, NULL, NULL, progress)); + RINOK(copyCoder->Code(inStreamLimited, outStream, NULL, NULL, progress)) return (copyCoderSpec->TotalSize == size ? S_OK : E_FAIL); } @@ -446,7 +564,7 @@ UString CUpdateItem::GetExtension() const } */ -#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; } +#define RINOZ(x) { const int _t_ = (x); if (_t_ != 0) return _t_; } #define RINOZ_COMP(a, b) RINOZ(MyCompare(a, b)) @@ -631,7 +749,7 @@ struct CRefItem unsigned NamePos; unsigned ExtensionIndex; - CRefItem() {}; + CRefItem() {} CRefItem(UInt32 index, const CUpdateItem &ui, bool sortByType): UpdateItem(&ui), Index(index), @@ -642,13 +760,13 @@ struct CRefItem if (sortByType) { int slashPos = ui.Name.ReverseFind_PathSepar(); - NamePos = slashPos + 1; + NamePos = (unsigned)(slashPos + 1); int dotPos = ui.Name.ReverseFind_Dot(); if (dotPos <= slashPos) ExtensionPos = ui.Name.Len(); else { - ExtensionPos = dotPos + 1; + ExtensionPos = (unsigned)(dotPos + 1); if (ExtensionPos != ui.Name.Len()) { AString s; @@ -711,16 +829,16 @@ static int CompareUpdateItems(const CRefItem *p1, const CRefItem *p2, void *para // bool sortByType = *(bool *)param; const CSortParam *sortParam = (const CSortParam *)param; - bool sortByType = sortParam->SortByType; + const bool sortByType = sortParam->SortByType; if (sortByType) { - RINOZ_COMP(a1.ExtensionIndex, a2.ExtensionIndex); - RINOZ(CompareFileNames(u1.Name.Ptr(a1.ExtensionPos), u2.Name.Ptr(a2.ExtensionPos))); - RINOZ(CompareFileNames(u1.Name.Ptr(a1.NamePos), u2.Name.Ptr(a2.NamePos))); + RINOZ_COMP(a1.ExtensionIndex, a2.ExtensionIndex) + RINOZ(CompareFileNames(u1.Name.Ptr(a1.ExtensionPos), u2.Name.Ptr(a2.ExtensionPos))) + RINOZ(CompareFileNames(u1.Name.Ptr(a1.NamePos), u2.Name.Ptr(a2.NamePos))) if (!u1.MTimeDefined && u2.MTimeDefined) return 1; if (u1.MTimeDefined && !u2.MTimeDefined) return -1; - if (u1.MTimeDefined && u2.MTimeDefined) RINOZ_COMP(u1.MTime, u2.MTime); - RINOZ_COMP(u1.Size, u2.Size); + if (u1.MTimeDefined && u2.MTimeDefined) RINOZ_COMP(u1.MTime, u2.MTime) + RINOZ_COMP(u1.Size, u2.Size) } /* int par1 = a1.UpdateItem->ParentFolderIndex; @@ -766,9 +884,9 @@ static int CompareUpdateItems(const CRefItem *p1, const CRefItem *p2, void *para } */ // RINOZ_COMP(a1.UpdateItem->ParentSortIndex, a2.UpdateItem->ParentSortIndex); - RINOK(CompareFileNames(u1.Name, u2.Name)); - RINOZ_COMP(a1.UpdateItem->IndexInClient, a2.UpdateItem->IndexInClient); - RINOZ_COMP(a1.UpdateItem->IndexInArchive, a2.UpdateItem->IndexInArchive); + RINOK(CompareFileNames(u1.Name, u2.Name)) + RINOZ_COMP(a1.UpdateItem->IndexInClient, a2.UpdateItem->IndexInClient) + RINOZ_COMP(a1.UpdateItem->IndexInArchive, a2.UpdateItem->IndexInArchive) return 0; } @@ -779,7 +897,7 @@ struct CSolidGroup CRecordVector<CFolderRepack> folderRefs; }; -static const char * const g_ExeExts[] = +static const char * const g_Exe_Exts[] = { "dll" , "exe" @@ -788,13 +906,64 @@ static const char * const g_ExeExts[] = , "sys" }; -static bool IsExeExt(const wchar_t *ext) +static const char * const g_ExeUnix_Exts[] = +{ + "so" + , "dylib" +}; + +static bool IsExt_Exe(const wchar_t *ext) +{ + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_Exe_Exts); i++) + if (StringsAreEqualNoCase_Ascii(ext, g_Exe_Exts[i])) + return true; + return false; +} + +/* +static bool IsExt_ExeUnix(const wchar_t *ext) { - for (unsigned i = 0; i < ARRAY_SIZE(g_ExeExts); i++) - if (StringsAreEqualNoCase_Ascii(ext, g_ExeExts[i])) + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_ExeUnix_Exts); i++) + if (StringsAreEqualNoCase_Ascii(ext, g_ExeUnix_Exts[i])) return true; return false; } +*/ + +// we try to find "so" extension in such name: libstdc++.so.6.0.29 +static bool IsExt_ExeUnix_NumericAllowed(const UString &path) +{ + unsigned pos = path.Len(); + unsigned dotPos = pos; + for (;;) + { + if (pos == 0) + return false; + const wchar_t c = path[--pos]; + if (IS_PATH_SEPAR(c)) + return false; + if (c == '.') + { + const unsigned num = (dotPos - pos) - 1; + if (num < 1) + return false; + const wchar_t *cur = path.Ptr(pos + 1); + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_ExeUnix_Exts); i++) + { + const char *ext = g_ExeUnix_Exts[i]; + if (num == MyStringLen(ext)) + if (IsString1PrefixedByString2_NoCase_Ascii(cur, ext)) + return true; + } + const wchar_t *end; + ConvertStringToUInt32(cur, &end); + if ((size_t)(end - cur) != num) + return false; + dotPos = pos; + } + } +} + struct CAnalysis { @@ -803,12 +972,26 @@ struct CAnalysis bool ParseWav; bool ParseExe; + bool ParseExeUnix; + bool ParseNoExt; bool ParseAll; + /* + bool Need_ATime; + bool ATime_Defined; + FILETIME ATime; + */ + CAnalysis(): - ParseWav(true), + ParseWav(false), ParseExe(false), + ParseExeUnix(false), + ParseNoExt(false), ParseAll(false) + /* + , Need_ATime(false) + , ATime_Defined(false) + */ {} HRESULT GetFilterGroup(UInt32 index, const CUpdateItem &ui, CFilterMode &filterMode); @@ -820,32 +1003,46 @@ HRESULT CAnalysis::GetFilterGroup(UInt32 index, const CUpdateItem &ui, CFilterMo { filterMode.Id = 0; filterMode.Delta = 0; + filterMode.Offset = 0; CFilterMode filterModeTemp = filterMode; - int slashPos = ui.Name.ReverseFind_PathSepar(); - int dotPos = ui.Name.ReverseFind_Dot(); + const int slashPos = ui.Name.ReverseFind_PathSepar(); + const int dotPos = ui.Name.ReverseFind_Dot(); // if (dotPos > slashPos) { bool needReadFile = ParseAll; - + /* if (Callback) is not supported by client, + we still try to use file name extension to detect executable file */ bool probablyIsSameIsa = false; if (!needReadFile || !Callback) { - const wchar_t *ext; + const wchar_t *ext = NULL; if (dotPos > slashPos) - ext = ui.Name.Ptr(dotPos + 1); - else - ext = ui.Name.RightPtr(0); - - // p7zip uses the trick to store posix attributes in high 16 bits + ext = ui.Name.Ptr((unsigned)(dotPos + 1)); + // 7-zip stores posix attributes in high 16 bits and sets (0x8000) flag if (ui.Attrib & 0x8000) { - unsigned st_mode = ui.Attrib >> 16; - // st_mode = 00111; - if ((st_mode & 00111) && (ui.Size >= 2048)) + const unsigned st_mode = ui.Attrib >> 16; + /* note: executable ".so" can be without execute permission, + and symbolic link to such ".so" file is possible */ + // st_mode = 00111; // for debug + /* in Linux we expect such permissions: + 0755 : for most executables + 0644 : for some ".so" files + 0777 : in WSL for all files. + We can try to exclude some such 0777 cases from analysis, + if there is non-executable extension. + */ + + if ((st_mode & ( + MY_LIN_S_IXUSR | + MY_LIN_S_IXGRP | + MY_LIN_S_IXOTH)) != 0 + && MY_LIN_S_ISREG(st_mode) + && (ui.Size >= (1u << 11))) { #ifndef _WIN32 probablyIsSameIsa = true; @@ -854,73 +1051,114 @@ HRESULT CAnalysis::GetFilterGroup(UInt32 index, const CUpdateItem &ui, CFilterMo } } - if (IsExeExt(ext)) + if (!needReadFile) { - needReadFile = true; - #ifdef _WIN32 - probablyIsSameIsa = true; - needReadFile = ParseExe; - #endif - } - else if (StringsAreEqualNoCase_Ascii(ext, "wav")) - { - needReadFile = ParseWav; - } - /* - else if (!needReadFile && ParseUnixExt) - { - if (StringsAreEqualNoCase_Ascii(ext, "so") - || StringsAreEqualNoCase_Ascii(ext, "")) - - needReadFile = true; + if (!ext) + needReadFile = ParseNoExt; + else + { + bool isUnixExt = false; + if (ParseExeUnix) + isUnixExt = IsExt_ExeUnix_NumericAllowed(ui.Name); + if (isUnixExt) + { + needReadFile = true; + #ifndef _WIN32 + probablyIsSameIsa = true; + #endif + } + else if (IsExt_Exe(ext)) + { + needReadFile = ParseExe; + #ifdef _WIN32 + probablyIsSameIsa = true; + #endif + } + else if (StringsAreEqualNoCase_Ascii(ext, "wav")) + { + if (!needReadFile) + needReadFile = ParseWav; + } + } } - */ } - if (needReadFile && Callback) + if (needReadFile) { - if (Buffer.Size() != kAnalysisBufSize) - { - Buffer.Alloc(kAnalysisBufSize); - } + BoolInt parseRes = false; + if (Callback) { + if (Buffer.Size() != kAnalysisBufSize) + Buffer.Alloc(kAnalysisBufSize); CMyComPtr<ISequentialInStream> stream; HRESULT result = Callback->GetStream2(index, &stream, NUpdateNotifyOp::kAnalyze); if (result == S_OK && stream) { + /* + if (Need_ATime) + { + // access time could be changed in analysis pass + CMyComPtr<IStreamGetProps> getProps; + stream.QueryInterface(IID_IStreamGetProps, (void **)&getProps); + if (getProps) + if (getProps->GetProps(NULL, NULL, &ATime, NULL, NULL) == S_OK) + ATime_Defined = true; + } + */ size_t size = kAnalysisBufSize; result = ReadStream(stream, Buffer, &size); stream.Release(); // RINOK(Callback->SetOperationResult2(index, NUpdate::NOperationResult::kOK)); if (result == S_OK) { - Bool parseRes = ParseFile(Buffer, size, &filterModeTemp); - if (parseRes && filterModeTemp.Delta == 0) - { - filterModeTemp.SetDelta(); - if (filterModeTemp.Delta != 0 && filterModeTemp.Id != k_Delta) - { - if (ui.Size % filterModeTemp.Delta != 0) - { - parseRes = false; - } - } - } - if (!parseRes) + parseRes = ParseFile(Buffer, size, &filterModeTemp); + } + } + } // Callback + else if (probablyIsSameIsa) + { + #ifdef MY_CPU_X86_OR_AMD64 + filterModeTemp.Id = k_X86; + #endif + #ifdef MY_CPU_ARM64 + filterModeTemp.Id = k_ARM64; + #endif + parseRes = true; + } + + if (parseRes + && filterModeTemp.Id != k_Delta + && filterModeTemp.Delta == 0) + { + /* ParseFile() sets (filterModeTemp.Delta == 0) for all + methods except of k_Delta. */ + // it's not k_Delta + // So we call SetDelta() to set Delta + filterModeTemp.SetDelta(); + if (filterModeTemp.Delta > 1) + { + /* If file Size is not aligned, then branch filter + will not work for next file in solid block. + Maybe we should allow filter for non-aligned-size file in non-solid archives ? + */ + if (ui.Size % filterModeTemp.Delta != 0) + parseRes = false; + // windows exe files are not aligned for 4 KiB. + /* + else if (filterModeTemp.Id == k_ARM64 && filterModeTemp.Offset != 0) + { + if (ui.Size % (1 << 12) != 0) { - filterModeTemp.Id = 0; - filterModeTemp.Delta = 0; + // If Size is not aligned for 4 KiB, then Offset will not work for next file in solid block. + // so we place such file in group with (Offset==0). + filterModeTemp.Offset = 0; } } + */ } } - } - else if ((needReadFile && !Callback) || probablyIsSameIsa) - { - #ifdef MY_CPU_X86_OR_AMD64 - if (probablyIsSameIsa) - filterModeTemp.Id = k_X86; - #endif + if (!parseRes) + filterModeTemp.ClearFilterMode(); } } @@ -989,7 +1227,7 @@ static HRESULT AddBcj2Methods(CCompressionMethodMode &mode) mode.Methods.Add(m); mode.Methods.Add(m); - RINOK(AddBondForFilter(mode)); + RINOK(AddBondForFilter(mode)) CBond2 bond; bond.OutCoder = 0; bond.InCoder = methodIndex; bond.OutStream = 1; mode.Bonds.Add(bond); @@ -1003,7 +1241,7 @@ static HRESULT MakeExeMethod(CCompressionMethodMode &mode, if (mode.Filter_was_Inserted) { const CMethodFull &m = mode.Methods[0]; - CMethodId id = m.Id; + const CMethodId id = m.Id; if (id == k_BCJ2) return AddBcj2Methods(mode); if (!m.IsSimpleCoder()) @@ -1018,7 +1256,7 @@ static HRESULT MakeExeMethod(CCompressionMethodMode &mode, CMethodFull &m = mode.Methods.InsertNew(0); { - FOR_VECTOR(k, mode.Bonds) + FOR_VECTOR (k, mode.Bonds) { CBond2 &bond = mode.Bonds[k]; bond.InCoder++; @@ -1038,23 +1276,32 @@ static HRESULT MakeExeMethod(CCompressionMethodMode &mode, GetMethodFull(filterMode.Id, 1, m); if (filterMode.Id == k_Delta) m.AddProp32(NCoderPropID::kDefaultProp, filterMode.Delta); + else if (filterMode.Id == k_ARM64) + { + // if (filterMode.Offset != 0) + m.AddProp32( + NCoderPropID::kDefaultProp, + // NCoderPropID::kBranchOffset, + filterMode.Offset); + } res = AddFilterBond(mode); int alignBits = -1; - if (filterMode.Id == k_Delta || filterMode.Delta != 0) - { - if (filterMode.Delta == 1) alignBits = 0; - else if (filterMode.Delta == 2) alignBits = 1; - else if (filterMode.Delta == 4) alignBits = 2; - else if (filterMode.Delta == 8) alignBits = 3; - else if (filterMode.Delta == 16) alignBits = 4; - } - else { - // alignBits = GetAlignForFilterMethod(filterMode.Id); + const UInt32 delta = filterMode.Delta; + if (delta == 0 || delta > 16) + { + // if (delta == 0) alignBits = GetAlignForFilterMethod(filterMode.Id); + } + else if ((delta & ((1 << 4) - 1)) == 0) alignBits = 4; + else if ((delta & ((1 << 3) - 1)) == 0) alignBits = 3; + else if ((delta & ((1 << 2) - 1)) == 0) alignBits = 2; + else if ((delta & ((1 << 1) - 1)) == 0) alignBits = 1; + // else alignBits = 0; + /* alignBits=0 is default mode for lzma/lzma2. + So we don't set alignBits=0 here. */ } - - if (res == S_OK && alignBits >= 0) + if (res == S_OK && alignBits > 0) { unsigned nextCoder = 1; if (!mode.Bonds.IsEmpty()) @@ -1071,12 +1318,12 @@ static HRESULT MakeExeMethod(CCompressionMethodMode &mode, if (alignBits != 0) { if (alignBits > 2 || filterMode.Id == k_Delta) - nextMethod.AddProp32(NCoderPropID::kPosStateBits, alignBits); + nextMethod.AddProp32(NCoderPropID::kPosStateBits, (unsigned)alignBits); unsigned lc = 0; if (alignBits < 3) - lc = 3 - alignBits; + lc = (unsigned)(3 - alignBits); nextMethod.AddProp32(NCoderPropID::kLitContextBits, lc); - nextMethod.AddProp32(NCoderPropID::kLitPosBits, alignBits); + nextMethod.AddProp32(NCoderPropID::kLitPosBits, (unsigned)alignBits); } } } @@ -1088,18 +1335,23 @@ static HRESULT MakeExeMethod(CCompressionMethodMode &mode, } -static void FromUpdateItemToFileItem(const CUpdateItem &ui, - CFileItem &file, CFileItem2 &file2) +static void UpdateItem_To_FileItem2(const CUpdateItem &ui, CFileItem2 &file2) { - if (ui.AttribDefined) - file.SetAttrib(ui.Attrib); - + file2.Attrib = ui.Attrib; file2.AttribDefined = ui.AttribDefined; file2.CTime = ui.CTime; file2.CTimeDefined = ui.CTimeDefined; file2.ATime = ui.ATime; file2.ATimeDefined = ui.ATimeDefined; file2.MTime = ui.MTime; file2.MTimeDefined = ui.MTimeDefined; file2.IsAnti = ui.IsAnti; // file2.IsAux = false; file2.StartPosDefined = false; + // file2.StartPos = 0; +} + + +static void UpdateItem_To_FileItem(const CUpdateItem &ui, + CFileItem &file, CFileItem2 &file2) +{ + UpdateItem_To_FileItem2(ui, file2); file.Size = ui.Size; file.IsDir = ui.IsDir; @@ -1107,13 +1359,15 @@ static void FromUpdateItemToFileItem(const CUpdateItem &ui, // file.IsAltStream = ui.IsAltStream; } -class CRepackInStreamWithSizes: - public ISequentialInStream, - public ICompressGetSubStreamSize, - public CMyUnknownImp -{ + + +Z7_CLASS_IMP_COM_2( + CRepackInStreamWithSizes + , ISequentialInStream + , ICompressGetSubStreamSize +) CMyComPtr<ISequentialInStream> _stream; - // UInt64 _size; + UInt64 _size; const CBoolVector *_extractStatuses; UInt32 _startIndex; public: @@ -1123,37 +1377,28 @@ public: { _startIndex = startIndex; _extractStatuses = extractStatuses; - // _size = 0; + _size = 0; _stream = stream; } - // UInt64 GetSize() const { return _size; } - - MY_UNKNOWN_IMP2(ISequentialInStream, ICompressGetSubStreamSize) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - - STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value); + UInt64 GetSize() const { return _size; } }; -STDMETHODIMP CRepackInStreamWithSizes::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CRepackInStreamWithSizes::Read(void *data, UInt32 size, UInt32 *processedSize)) { - return _stream->Read(data, size, processedSize); - /* UInt32 realProcessedSize; - HRESULT result = _stream->Read(data, size, &realProcessedSize); + const HRESULT result = _stream->Read(data, size, &realProcessedSize); _size += realProcessedSize; if (processedSize) *processedSize = realProcessedSize; return result; - */ } -STDMETHODIMP CRepackInStreamWithSizes::GetSubStreamSize(UInt64 subStream, UInt64 *value) +Z7_COM7F_IMF(CRepackInStreamWithSizes::GetSubStreamSize(UInt64 subStream, UInt64 *value)) { *value = 0; if (subStream >= _extractStatuses->Size()) return S_FALSE; // E_FAIL; - unsigned index = (unsigned)subStream; + const unsigned index = (unsigned)subStream; if ((*_extractStatuses)[index]) { const CFileItem &fi = _db->Files[_startIndex + index]; @@ -1184,7 +1429,7 @@ protected: public: const CDbEx *_db; CMyComPtr<IArchiveUpdateCallbackFile> _opCallback; - CMyComPtr<IArchiveExtractCallbackMessage> _extractCallback; + CMyComPtr<IArchiveExtractCallbackMessage2> _extractCallback; HRESULT Init(UInt32 startIndex, const CBoolVector *extractStatuses); HRESULT CheckFinishedState() const { return (_currentIndex == _extractStatuses->Size()) ? S_OK: E_FAIL; } @@ -1213,7 +1458,7 @@ HRESULT CRepackStreamBase::OpenFile() NEventIndexType::kInArcIndex, arcIndex, _needWrite ? NUpdateNotifyOp::kRepack : - NUpdateNotifyOp::kSkip)); + NUpdateNotifyOp::kSkip)) } _crc = CRC_INIT_VAL; @@ -1239,7 +1484,7 @@ HRESULT CRepackStreamBase::CloseFile() { RINOK(_extractCallback->ReportExtractResult( NEventIndexType::kInArcIndex, arcIndex, - NExtract::NOperationResult::kCRCError)); + NExtract::NOperationResult::kCRCError)) } // return S_FALSE; return k_My_HRESULT_CRC_ERROR; @@ -1249,30 +1494,28 @@ HRESULT CRepackStreamBase::ProcessEmptyFiles() { while (_currentIndex < _extractStatuses->Size() && _db->Files[_startIndex + _currentIndex].Size == 0) { - RINOK(OpenFile()); - RINOK(CloseFile()); + RINOK(OpenFile()) + RINOK(CloseFile()) } return S_OK; } -#ifndef _7ZIP_ST +#ifndef Z7_ST -class CFolderOutStream2: +class CFolderOutStream2 Z7_final: public CRepackStreamBase, public ISequentialOutStream, public CMyUnknownImp { + Z7_COM_UNKNOWN_IMP_0 + Z7_IFACE_COM7_IMP(ISequentialOutStream) public: CMyComPtr<ISequentialOutStream> _stream; - - MY_UNKNOWN_IMP - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); }; -STDMETHODIMP CFolderOutStream2::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CFolderOutStream2::Write(const void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -1294,22 +1537,22 @@ STDMETHODIMP CFolderOutStream2::Write(const void *data, UInt32 size, UInt32 *pro _rem -= cur; if (_rem == 0) { - RINOK(CloseFile()); - RINOK(ProcessEmptyFiles()); + RINOK(CloseFile()) + RINOK(ProcessEmptyFiles()) } - RINOK(result); + RINOK(result) if (cur == 0) break; continue; } - RINOK(ProcessEmptyFiles()); + RINOK(ProcessEmptyFiles()) if (_currentIndex == _extractStatuses->Size()) { // we don't support write cut here return E_FAIL; } - RINOK(OpenFile()); + RINOK(OpenFile()) } return S_OK; @@ -1321,18 +1564,19 @@ STDMETHODIMP CFolderOutStream2::Write(const void *data, UInt32 size, UInt32 *pro static const UInt32 kTempBufSize = 1 << 16; -class CFolderInStream2: +class CFolderInStream2 Z7_final: public CRepackStreamBase, public ISequentialInStream, public CMyUnknownImp { + Z7_COM_UNKNOWN_IMP_0 + Z7_IFACE_COM7_IMP(ISequentialInStream) + Byte *_buf; public: CMyComPtr<ISequentialInStream> _inStream; HRESULT Result; - MY_UNKNOWN_IMP - CFolderInStream2(): Result(S_OK) { @@ -1345,10 +1589,9 @@ public: } void Init() { Result = S_OK; } - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); }; -STDMETHODIMP CFolderInStream2::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CFolderInStream2::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -1369,7 +1612,7 @@ STDMETHODIMP CFolderInStream2::Read(void *data, UInt32 size, UInt32 *processedSi cur = kTempBufSize; } - HRESULT result = _inStream->Read(buf, cur, &cur); + const HRESULT result = _inStream->Read(buf, cur, &cur); _crc = CrcUpdate(_crc, buf, cur); _rem -= cur; @@ -1386,11 +1629,11 @@ STDMETHODIMP CFolderInStream2::Read(void *data, UInt32 size, UInt32 *processedSi if (_rem == 0) { - RINOK(CloseFile()); - RINOK(ProcessEmptyFiles()); + RINOK(CloseFile()) + RINOK(ProcessEmptyFiles()) } - RINOK(result); + RINOK(result) if (cur == 0) return E_FAIL; @@ -1398,20 +1641,20 @@ STDMETHODIMP CFolderInStream2::Read(void *data, UInt32 size, UInt32 *processedSi continue; } - RINOK(ProcessEmptyFiles()); + RINOK(ProcessEmptyFiles()) if (_currentIndex == _extractStatuses->Size()) { return S_OK; } - RINOK(OpenFile()); + RINOK(OpenFile()) } return S_OK; } -class CThreadDecoder - #ifndef _7ZIP_ST +class CThreadDecoder Z7_final + #ifndef Z7_ST : public CVirtThread #endif { @@ -1421,7 +1664,7 @@ public: CThreadDecoder(bool multiThreadMixer): Decoder(multiThreadMixer) { - #ifndef _7ZIP_ST + #ifndef Z7_ST if (multiThreadMixer) { MtMode = false; @@ -1435,8 +1678,9 @@ public: // send_UnpackSize = false; } - #ifndef _7ZIP_ST + #ifndef Z7_ST + bool dataAfterEnd_Error; HRESULT Result; CMyComPtr<IInStream> InStream; @@ -1445,41 +1689,51 @@ public: UInt64 StartPos; const CFolders *Folders; - int FolderIndex; + unsigned FolderIndex; // bool send_UnpackSize; // UInt64 UnpackSize; - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO CMyComPtr<ICryptoGetTextPassword> getTextPassword; #endif - DECL_EXTERNAL_CODECS_LOC_VARS2; + DECL_EXTERNAL_CODECS_LOC_VARS_DECL - #ifndef _7ZIP_ST + #ifndef Z7_ST bool MtMode; UInt32 NumThreads; #endif - ~CThreadDecoder() { CVirtThread::WaitThreadFinish(); } - virtual void Execute(); + ~CThreadDecoder() Z7_DESTRUCTOR_override + { + /* WaitThreadFinish() will be called in ~CVirtThread(). + But we need WaitThreadFinish() call before + destructors of this class members. + */ + CVirtThread::WaitThreadFinish(); + } +private: + virtual void Execute() Z7_override; #endif }; -#ifndef _7ZIP_ST +#ifndef Z7_ST void CThreadDecoder::Execute() { try { - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO bool isEncrypted = false; bool passwordIsDefined = false; UString password; #endif - + + dataAfterEnd_Error = false; + Result = Decoder.Decode( EXTERNAL_CODECS_LOC_VARS InStream, @@ -1491,12 +1745,16 @@ void CThreadDecoder::Execute() Fos, NULL, // compressProgress + NULL // *inStreamMainRes + , dataAfterEnd_Error - _7Z_DECODER_CRYPRO_VARS - #ifndef _7ZIP_ST - , MtMode, NumThreads + Z7_7Z_DECODER_CRYPRO_VARS + #ifndef Z7_ST + , MtMode, NumThreads, + 0 // MemUsage #endif + ); } catch(...) @@ -1513,20 +1771,17 @@ void CThreadDecoder::Execute() #endif -#ifndef _NO_CRYPTO +#ifndef Z7_NO_CRYPTO -class CCryptoGetTextPassword: - public ICryptoGetTextPassword, - public CMyUnknownImp -{ +Z7_CLASS_IMP_NOQIB_1( + CCryptoGetTextPassword + , ICryptoGetTextPassword +) public: UString Password; - - MY_UNKNOWN_IMP - STDMETHOD(CryptoGetTextPassword)(BSTR *password); }; -STDMETHODIMP CCryptoGetTextPassword::CryptoGetTextPassword(BSTR *password) +Z7_COM7F_IMF(CCryptoGetTextPassword::CryptoGetTextPassword(BSTR *password)) { return StringToBstr(Password, password); } @@ -1541,6 +1796,7 @@ static void GetFile(const CDatabase &inDb, unsigned index, CFileItem &file, CFil file2.ATimeDefined = inDb.ATime.GetItem(index, file2.ATime); file2.MTimeDefined = inDb.MTime.GetItem(index, file2.MTime); file2.StartPosDefined = inDb.StartPos.GetItem(index, file2.StartPos); + file2.AttribDefined = inDb.Attrib.GetItem(index, file2.Attrib); file2.IsAnti = inDb.IsItemAnti(index); // file2.IsAux = inDb.IsItemAux(index); } @@ -1549,52 +1805,72 @@ HRESULT Update( DECL_EXTERNAL_CODECS_LOC_VARS IInStream *inStream, const CDbEx *db, - const CObjectVector<CUpdateItem> &updateItems, + CObjectVector<CUpdateItem> &updateItems, // const CObjectVector<CTreeFolder> &treeFolders, // const CUniqBlocks &secureBlocks, - COutArchive &archive, - CArchiveDatabaseOut &newDatabase, ISequentialOutStream *seqOutStream, IArchiveUpdateCallback *updateCallback, - const CUpdateOptions &options - #ifndef _NO_CRYPTO - , ICryptoGetTextPassword *getDecoderPassword - #endif - ) + const CUpdateOptions &options) { UInt64 numSolidFiles = options.NumSolidFiles; if (numSolidFiles == 0) numSolidFiles = 1; - CMyComPtr<IArchiveUpdateCallbackFile> opCallback; - updateCallback->QueryInterface(IID_IArchiveUpdateCallbackFile, (void **)&opCallback); + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveUpdateCallbackFile, + opCallback, updateCallback) - CMyComPtr<IArchiveExtractCallbackMessage> extractCallback; - updateCallback->QueryInterface(IID_IArchiveExtractCallbackMessage, (void **)&extractCallback); - - // size_t totalSecureDataSize = (size_t)secureBlocks.GetTotalSizeInBytes(); + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveExtractCallbackMessage2, + extractCallback, updateCallback) /* - CMyComPtr<IOutStream> outStream; - RINOK(seqOutStream->QueryInterface(IID_IOutStream, (void **)&outStream)); - if (!outStream) - return E_NOTIMPL; + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveUpdateCallbackArcProp, + reportArcProp, updateCallback) */ - UInt64 startBlockSize = db ? db->ArcInfo.StartPosition: 0; - if (startBlockSize > 0 && !options.RemoveSfxBlock) + // size_t totalSecureDataSize = (size_t)secureBlocks.GetTotalSizeInBytes(); + + CMyComPtr<IStreamSetRestriction> v_StreamSetRestriction; { - RINOK(WriteRange(inStream, seqOutStream, 0, startBlockSize, NULL)); + Z7_DECL_CMyComPtr_QI_FROM( + IOutStream, + outStream, seqOutStream) + if (!outStream) + return E_NOTIMPL; + const UInt64 sfxBlockSize = (db && !options.RemoveSfxBlock) ? + db->ArcInfo.StartPosition: 0; + seqOutStream->QueryInterface(IID_IStreamSetRestriction, (void **)&v_StreamSetRestriction); + if (v_StreamSetRestriction) + { + UInt64 offset = 0; + RINOK(outStream->Seek(0, STREAM_SEEK_CUR, &offset)) + RINOK(v_StreamSetRestriction->SetRestriction( + outStream ? offset + sfxBlockSize : 0, + outStream ? offset + sfxBlockSize + k_StartHeadersRewriteSize : 0)) + } + outStream.Release(); + if (sfxBlockSize != 0) + { + RINOK(WriteRange(inStream, seqOutStream, 0, sfxBlockSize, NULL)) + } } CIntArr fileIndexToUpdateIndexMap; UInt64 complexity = 0; UInt64 inSizeForReduce2 = 0; + + #ifndef Z7_NO_CRYPTO bool needEncryptedRepack = false; + #endif CRecordVector<CFilterMode2> filters; CObjectVector<CSolidGroup> groups; + + #ifndef Z7_ST bool thereAreRepacks = false; + #endif bool useFilters = options.UseFilters; if (useFilters) @@ -1602,11 +1878,15 @@ HRESULT Update( const CCompressionMethodMode &method = *options.Method; FOR_VECTOR (i, method.Methods) + { + /* IsFilterMethod() knows only built-in codecs + FIXME: we should check IsFilter status for external filters too */ if (IsFilterMethod(method.Methods[i].Id)) { useFilters = false; break; } + } } if (db) @@ -1621,24 +1901,27 @@ HRESULT Update( { int index = updateItems[i].IndexInArchive; if (index != -1) - fileIndexToUpdateIndexMap[(unsigned)index] = i; + fileIndexToUpdateIndexMap[(unsigned)index] = (int)i; } for (i = 0; i < db->NumFolders; i++) { CNum indexInFolder = 0; CNum numCopyItems = 0; - CNum numUnpackStreams = db->NumUnpackStreamsVector[i]; + const CNum numUnpackStreams = db->NumUnpackStreamsVector[i]; UInt64 repackSize = 0; for (CNum fi = db->FolderStartFileIndex[i]; indexInFolder < numUnpackStreams; fi++) { + if (fi >= db->Files.Size()) + return E_FAIL; + const CFileItem &file = db->Files[fi]; if (file.HasStream) { indexInFolder++; - int updateIndex = fileIndexToUpdateIndexMap[fi]; - if (updateIndex >= 0 && !updateItems[updateIndex].NewData) + const int updateIndex = fileIndexToUpdateIndexMap[fi]; + if (updateIndex >= 0 && !updateItems[(unsigned)updateIndex].NewData) { numCopyItems++; repackSize += file.Size; @@ -1655,11 +1938,13 @@ HRESULT Update( CFolderEx f; db->ParseFolderEx(i, f); + #ifndef Z7_NO_CRYPTO const bool isEncrypted = f.IsEncrypted(); + #endif const bool needCopy = (numCopyItems == numUnpackStreams); const bool extractFilter = (useFilters || needCopy); - unsigned groupIndex = Get_FilterGroup_for_Folder(filters, f, extractFilter); + const unsigned groupIndex = Get_FilterGroup_for_Folder(filters, f, extractFilter); while (groupIndex >= groups.Size()) groups.AddNew(); @@ -1670,25 +1955,30 @@ HRESULT Update( complexity += db->GetFolderFullPackSize(i); else { + #ifndef Z7_ST thereAreRepacks = true; + #endif complexity += repackSize; if (inSizeForReduce2 < repackSize) inSizeForReduce2 = repackSize; + #ifndef Z7_NO_CRYPTO if (isEncrypted) needEncryptedRepack = true; + #endif } } } UInt64 inSizeForReduce = 0; { + bool isSolid = (numSolidFiles > 1 && options.NumSolidBytes != 0); FOR_VECTOR (i, updateItems) { const CUpdateItem &ui = updateItems[i]; if (ui.NewData) { complexity += ui.Size; - if (numSolidFiles != 1) + if (isSolid) inSizeForReduce += ui.Size; else if (inSizeForReduce < ui.Size) inSizeForReduce = ui.Size; @@ -1699,52 +1989,58 @@ HRESULT Update( if (inSizeForReduce < inSizeForReduce2) inSizeForReduce = inSizeForReduce2; - RINOK(updateCallback->SetTotal(complexity)); + RINOK(updateCallback->SetTotal(complexity)) CLocalProgress *lps = new CLocalProgress; CMyComPtr<ICompressProgressInfo> progress = lps; lps->Init(updateCallback, true); - #ifndef _7ZIP_ST + #ifndef Z7_ST CStreamBinder sb; + /* if (options.MultiThreadMixer) { RINOK(sb.CreateEvents()); } + */ #endif CThreadDecoder threadDecoder(options.MultiThreadMixer); - #ifndef _7ZIP_ST + #ifndef Z7_ST if (options.MultiThreadMixer && thereAreRepacks) { - #ifdef EXTERNAL_CODECS - threadDecoder.__externalCodecs = __externalCodecs; + #ifdef Z7_EXTERNAL_CODECS + threadDecoder._externalCodecs = _externalCodecs; #endif - RINOK(threadDecoder.Create()); + const WRes wres = threadDecoder.Create(); + if (wres != 0) + return HRESULT_FROM_WIN32(wres); } #endif { CAnalysis analysis; - if (options.AnalysisLevel == 0) - { - analysis.ParseWav = false; - analysis.ParseExe = false; - analysis.ParseAll = false; - } - else + // analysis.Need_ATime = options.Need_ATime; + int analysisLevel = options.AnalysisLevel; + // (analysisLevel < 0) means default level (5) + if (analysisLevel < 0) + analysisLevel = 5; + if (analysisLevel != 0) { analysis.Callback = opCallback; - if (options.AnalysisLevel > 0) + analysis.ParseWav = true; + if (analysisLevel >= 5) { - analysis.ParseWav = true; - if (options.AnalysisLevel >= 7) + analysis.ParseExe = true; + analysis.ParseExeUnix = true; + // analysis.ParseNoExt = true; + if (analysisLevel >= 7) { - analysis.ParseExe = true; - if (options.AnalysisLevel >= 9) + analysis.ParseNoExt = true; + if (analysisLevel >= 9) analysis.ParseAll = true; } } @@ -1763,11 +2059,19 @@ HRESULT Update( CFilterMode2 fm; if (useFilters) { - RINOK(analysis.GetFilterGroup(i, ui, fm)); + // analysis.ATime_Defined = false; + RINOK(analysis.GetFilterGroup(i, ui, fm)) + /* + if (analysis.ATime_Defined) + { + ui.ATime = FILETIME_To_UInt64(analysis.ATime); + ui.ATime_WasReadByAnalysis = true; + } + */ } fm.Encrypted = method.PasswordIsDefined; - unsigned groupIndex = GetGroup(filters, fm); + const unsigned groupIndex = GetGroup(filters, fm); while (groupIndex >= groups.Size()) groups.AddNew(); groups[groupIndex].Indices.Add(i); @@ -1775,7 +2079,7 @@ HRESULT Update( } - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO CCryptoGetTextPassword *getPasswordSpec = NULL; CMyComPtr<ICryptoGetTextPassword> getTextPassword; @@ -1784,7 +2088,7 @@ HRESULT Update( getPasswordSpec = new CCryptoGetTextPassword; getTextPassword = getPasswordSpec; - #ifndef _7ZIP_ST + #ifndef Z7_ST threadDecoder.getTextPassword = getPasswordSpec; #endif @@ -1792,10 +2096,13 @@ HRESULT Update( getPasswordSpec->Password = options.Method->Password; else { + Z7_DECL_CMyComPtr_QI_FROM( + ICryptoGetTextPassword, + getDecoderPassword, updateCallback) if (!getDecoderPassword) return E_NOTIMPL; CMyComBSTR password; - RINOK(getDecoderPassword->CryptoGetTextPassword(&password)); + RINOK(getDecoderPassword->CryptoGetTextPassword(&password)) if (password) getPasswordSpec->Password = password; } @@ -1803,11 +2110,12 @@ HRESULT Update( #endif - // ---------- Compress ---------- - RINOK(archive.Create(seqOutStream, false)); - RINOK(archive.SkipPrefixArchiveHeader()); + COutArchive archive; + CArchiveDatabaseOut newDatabase; + + RINOK(archive.Create_and_WriteStartPrefix(seqOutStream)) /* CIntVector treeFolderToArcIndex; @@ -1837,7 +2145,7 @@ HRESULT Update( continue; secureID = ui.SecureIndex; if (ui.NewProps) - FromUpdateItemToFileItem(ui, file, file2); + UpdateItem_To_FileItem(ui, file, file2); else GetFile(*db, ui.IndexInArchive, file, file2); } @@ -1868,7 +2176,7 @@ HRESULT Update( if (ui.HasStream()) continue; } - else if (ui.IndexInArchive != -1 && db->Files[ui.IndexInArchive].HasStream) + else if (ui.IndexInArchive != -1 && db->Files[(unsigned)ui.IndexInArchive].HasStream) continue; /* if (ui.TreeFolderIndex >= 0) @@ -1887,13 +2195,14 @@ HRESULT Update( UString name; if (ui.NewProps) { - FromUpdateItemToFileItem(ui, file, file2); + UpdateItem_To_FileItem(ui, file, file2); + file.CrcDefined = false; name = ui.Name; } else { - GetFile(*db, ui.IndexInArchive, file, file2); - db->GetPath(ui.IndexInArchive, name); + GetFile(*db, (unsigned)ui.IndexInArchive, file, file2); + db->GetPath((unsigned)ui.IndexInArchive, name); } /* @@ -1909,7 +2218,6 @@ HRESULT Update( { // ---------- Sort Filters ---------- - FOR_VECTOR (i, filters) { filters[i].GroupIndex = i; @@ -1923,22 +2231,22 @@ HRESULT Update( CCompressionMethodMode method = *options.Method; { - HRESULT res = MakeExeMethod(method, filterMode, - #ifdef _7ZIP_ST + const HRESULT res = MakeExeMethod(method, filterMode, + #ifdef Z7_ST false #else options.MaxFilter && options.MultiThreadMixer #endif ); - RINOK(res); + RINOK(res) } if (filterMode.Encrypted) { if (!method.PasswordIsDefined) { - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO if (getPasswordSpec) method.Password = getPasswordSpec->Password; #endif @@ -1957,13 +2265,13 @@ HRESULT Update( const CSolidGroup &group = groups[filterMode.GroupIndex]; - FOR_VECTOR(folderRefIndex, group.folderRefs) + FOR_VECTOR (folderRefIndex, group.folderRefs) { const CFolderRepack &rep = group.folderRefs[folderRefIndex]; - unsigned folderIndex = rep.FolderIndex; + const unsigned folderIndex = rep.FolderIndex; - CNum numUnpackStreams = db->NumUnpackStreamsVector[folderIndex]; + const CNum numUnpackStreams = db->NumUnpackStreamsVector[folderIndex]; if (rep.NumCopyFiles == numUnpackStreams) { @@ -1971,7 +2279,7 @@ HRESULT Update( { RINOK(opCallback->ReportOperation( NEventIndexType::kBlockIndex, (UInt32)folderIndex, - NUpdateNotifyOp::kReplicate)); + NUpdateNotifyOp::kReplicate)) // ---------- Copy old solid block ---------- { @@ -1983,21 +2291,27 @@ HRESULT Update( indexInFolder++; RINOK(opCallback->ReportOperation( NEventIndexType::kInArcIndex, (UInt32)fi, - NUpdateNotifyOp::kReplicate)); + NUpdateNotifyOp::kReplicate)) } } } } - UInt64 packSize = db->GetFolderFullPackSize(folderIndex); + const UInt64 packSize = db->GetFolderFullPackSize(folderIndex); RINOK(WriteRange(inStream, archive.SeqStream, - db->GetFolderStreamPos(folderIndex, 0), packSize, progress)); + db->GetFolderStreamPos(folderIndex, 0), packSize, progress)) lps->ProgressOffset += packSize; - + + const unsigned folderIndex_New = newDatabase.Folders.Size(); CFolder &folder = newDatabase.Folders.AddNew(); + // v23.01: we copy FolderCrc, if FolderCrc was used + if (db->FolderCRCs.ValidAndDefined(folderIndex)) + newDatabase.FolderUnpackCRCs.SetItem(folderIndex_New, + true, db->FolderCRCs.Vals[folderIndex]); + db->ParseFolderInfo(folderIndex, folder); - CNum startIndex = db->FoStartPackStreamIndex[folderIndex]; - FOR_VECTOR(j, folder.PackStreams) + const CNum startIndex = db->FoStartPackStreamIndex[folderIndex]; + FOR_VECTOR (j, folder.PackStreams) { newDatabase.PackSizes.Add(db->GetStreamPackSize(startIndex + j)); // newDatabase.PackCRCsDefined.Add(db.PackCRCsDefined[startIndex + j]); @@ -2005,7 +2319,7 @@ HRESULT Update( } size_t indexStart = db->FoToCoderUnpackSizes[folderIndex]; - size_t indexEnd = db->FoToCoderUnpackSizes[folderIndex + 1]; + const size_t indexEnd = db->FoToCoderUnpackSizes[folderIndex + 1]; for (; indexStart < indexEnd; indexStart++) newDatabase.CoderUnpackSizes.Add(db->CoderUnpackSizes[indexStart]); } @@ -2044,8 +2358,8 @@ HRESULT Update( if (file.HasStream) { indexInFolder++; - int updateIndex = fileIndexToUpdateIndexMap[fi]; - if (updateIndex >= 0 && !updateItems[updateIndex].NewData) + const int updateIndex = fileIndexToUpdateIndexMap[fi]; + if (updateIndex >= 0 && !updateItems[(unsigned)updateIndex].NewData) needExtract = true; // decodeSize += file.Size; } @@ -2066,7 +2380,6 @@ HRESULT Update( unsigned startPackIndex = newDatabase.PackSizes.Size(); UInt64 curUnpackSize; { - CMyComPtr<ISequentialInStream> sbInStream; CRepackStreamBase *repackBase; CFolderInStream2 *FosSpec2 = NULL; @@ -2074,13 +2387,13 @@ HRESULT Update( CRepackInStreamWithSizes *inStreamSizeCountSpec = new CRepackInStreamWithSizes; CMyComPtr<ISequentialInStream> inStreamSizeCount = inStreamSizeCountSpec; { - #ifndef _7ZIP_ST + #ifndef Z7_ST if (options.MultiThreadMixer) { repackBase = threadDecoder.FosSpec; CMyComPtr<ISequentialOutStream> sbOutStream; - sb.CreateStreams(&sbInStream, &sbOutStream); - sb.ReInit(); + sb.CreateStreams2(sbInStream, sbOutStream); + RINOK(sb.Create_ReInit()) threadDecoder.FosSpec->_stream = sbOutStream; @@ -2100,14 +2413,16 @@ HRESULT Update( sbInStream = FosSpec2; repackBase = FosSpec2; - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO bool isEncrypted = false; bool passwordIsDefined = false; UString password; #endif CMyComPtr<ISequentialInStream> decodedStream; - HRESULT res = threadDecoder.Decoder.Decode( + bool dataAfterEnd_Error = false; + + const HRESULT res = threadDecoder.Decoder.Decode( EXTERNAL_CODECS_LOC_VARS inStream, db->ArcInfo.DataStartPosition, // db->GetFolderStreamPos(folderIndex, 0);, @@ -2117,16 +2432,19 @@ HRESULT Update( NULL, // *outStream NULL, // *compressProgress + &decodedStream + , dataAfterEnd_Error - _7Z_DECODER_CRYPRO_VARS - #ifndef _7ZIP_ST + Z7_7Z_DECODER_CRYPRO_VARS + #ifndef Z7_ST , false // mtMode , 1 // numThreads + , 0 // memUsage #endif ); - RINOK(res); + RINOK(res) if (!decodedStream) return E_FAIL; @@ -2138,32 +2456,44 @@ HRESULT Update( repackBase->_extractCallback = extractCallback; UInt32 startIndex = db->FolderStartFileIndex[folderIndex]; - RINOK(repackBase->Init(startIndex, &extractStatuses)); + RINOK(repackBase->Init(startIndex, &extractStatuses)) inStreamSizeCountSpec->_db = db; inStreamSizeCountSpec->Init(sbInStream, startIndex, &extractStatuses); - #ifndef _7ZIP_ST + #ifndef Z7_ST if (options.MultiThreadMixer) { - threadDecoder.Start(); + WRes wres = threadDecoder.Start(); + if (wres != 0) + return HRESULT_FROM_WIN32(wres); } #endif } + // curUnpackSize = sizeToEncode; - HRESULT encodeRes = encoder.Encode( + HRESULT encodeRes = encoder.Encode1( EXTERNAL_CODECS_LOC_VARS inStreamSizeCount, // NULL, &inSizeForReduce, - newDatabase.Folders.AddNew(), newDatabase.CoderUnpackSizes, curUnpackSize, + sizeToEncode, // expectedDataSize + newDatabase.Folders.AddNew(), + // newDatabase.CoderUnpackSizes, curUnpackSize, archive.SeqStream, newDatabase.PackSizes, progress); if (encodeRes == k_My_HRESULT_CRC_ERROR) return E_FAIL; - #ifndef _7ZIP_ST + curUnpackSize = inStreamSizeCountSpec->GetSize(); + + if (encodeRes == S_OK) + { + encoder.Encode_Post(curUnpackSize, newDatabase.CoderUnpackSizes); + } + + #ifndef Z7_ST if (options.MultiThreadMixer) { // 16.00: hang was fixed : for case if decoding was not finished. @@ -2171,22 +2501,29 @@ HRESULT Update( inStreamSizeCount.Release(); sbInStream.Release(); - threadDecoder.WaitExecuteFinish(); + { + const WRes wres = threadDecoder.WaitExecuteFinish(); + if (wres != 0) + return HRESULT_FROM_WIN32(wres); + } - HRESULT decodeRes = threadDecoder.Result; + const HRESULT decodeRes = threadDecoder.Result; // if (res == k_My_HRESULT_CRC_ERROR) - if (decodeRes == S_FALSE) + if (decodeRes == S_FALSE || threadDecoder.dataAfterEnd_Error) { if (extractCallback) { RINOK(extractCallback->ReportExtractResult( NEventIndexType::kInArcIndex, db->FolderStartFileIndex[folderIndex], // NEventIndexType::kBlockIndex, (UInt32)folderIndex, - NExtract::NOperationResult::kDataError)); + (decodeRes != S_OK ? + NExtract::NOperationResult::kDataError : + NExtract::NOperationResult::kDataAfterEnd))) } - return E_FAIL; + if (decodeRes != S_OK) + return E_FAIL; } - RINOK(decodeRes); + RINOK(decodeRes) if (encodeRes == S_OK) if (sb.ProcessedSize != sizeToEncode) encodeRes = E_FAIL; @@ -2200,15 +2537,15 @@ HRESULT Update( { RINOK(extractCallback->ReportExtractResult( NEventIndexType::kBlockIndex, (UInt32)folderIndex, - NExtract::NOperationResult::kDataError)); + NExtract::NOperationResult::kDataError)) } return E_FAIL; } - RINOK(FosSpec2->Result); + RINOK(FosSpec2->Result) } - RINOK(encodeRes); - RINOK(repackBase->CheckFinishedState()); + RINOK(encodeRes) + RINOK(repackBase->CheckFinishedState()) if (curUnpackSize != sizeToEncode) return E_FAIL; @@ -2224,31 +2561,30 @@ HRESULT Update( CNum indexInFolder = 0; for (CNum fi = db->FolderStartFileIndex[folderIndex]; indexInFolder < numUnpackStreams; fi++) { - CFileItem file; - CFileItem2 file2; - GetFile(*db, fi, file, file2); - UString name; - db->GetPath(fi, name); - if (file.HasStream) + if (db->Files[fi].HasStream) { indexInFolder++; - int updateIndex = fileIndexToUpdateIndexMap[fi]; + const int updateIndex = fileIndexToUpdateIndexMap[fi]; if (updateIndex >= 0) { - const CUpdateItem &ui = updateItems[updateIndex]; + const CUpdateItem &ui = updateItems[(unsigned)updateIndex]; if (ui.NewData) continue; + + UString name; + CFileItem file; + CFileItem2 file2; + GetFile(*db, fi, file, file2); + if (ui.NewProps) { - CFileItem uf; - FromUpdateItemToFileItem(ui, uf, file2); - uf.Size = file.Size; - uf.Crc = file.Crc; - uf.CrcDefined = file.CrcDefined; - uf.HasStream = file.HasStream; - file = uf; + UpdateItem_To_FileItem2(ui, file2); + file.IsDir = ui.IsDir; name = ui.Name; } + else + db->GetPath(fi, name); + /* file.Parent = ui.ParentFolderIndex; if (ui.TreeFolderIndex >= 0) @@ -2265,12 +2601,13 @@ HRESULT Update( // ---------- Compress files to new solid blocks ---------- - unsigned numFiles = group.Indices.Size(); + const unsigned numFiles = group.Indices.Size(); if (numFiles == 0) continue; CRecordVector<CRefItem> refItems; refItems.ClearAndSetSize(numFiles); - bool sortByType = (options.UseTypeSorting && numSolidFiles > 1); + // bool sortByType = (options.UseTypeSorting && isSoid); // numSolidFiles > 1 + const bool sortByType = options.UseTypeSorting; unsigned i; @@ -2286,13 +2623,13 @@ HRESULT Update( for (i = 0; i < numFiles; i++) { - UInt32 index = refItems[i].Index; + const UInt32 index = refItems[i].Index; indices[i] = index; /* const CUpdateItem &ui = updateItems[index]; CFileItem file; if (ui.NewProps) - FromUpdateItemToFileItem(ui, file); + UpdateItem_To_FileItem(ui, file); else file = db.Files[ui.IndexInArchive]; if (file.IsAnti || file.IsDir) @@ -2316,9 +2653,9 @@ HRESULT Update( break; if (options.SolidExtension) { - int slashPos = ui.Name.ReverseFind_PathSepar(); - int dotPos = ui.Name.ReverseFind_Dot(); - const wchar_t *ext = ui.Name.Ptr(dotPos <= slashPos ? ui.Name.Len() : dotPos + 1); + const int slashPos = ui.Name.ReverseFind_PathSepar(); + const int dotPos = ui.Name.ReverseFind_Dot(); + const wchar_t *ext = ui.Name.Ptr(dotPos <= slashPos ? ui.Name.Len() : (unsigned)(dotPos + 1)); if (numSubFiles == 0) prevExtension = ext; else if (!StringsAreEqualNoCase(ext, prevExtension)) @@ -2329,36 +2666,77 @@ HRESULT Update( if (numSubFiles < 1) numSubFiles = 1; - RINOK(lps->SetCur()); + RINOK(lps->SetCur()) + + /* + const unsigned folderIndex = newDatabase.NumUnpackStreamsVector.Size(); + + if (opCallback) + { + RINOK(opCallback->ReportOperation( + NEventIndexType::kBlockIndex, (UInt32)folderIndex, + NUpdateNotifyOp::kAdd)); + } + */ + CFolderInStream *inStreamSpec = new CFolderInStream; CMyComPtr<ISequentialInStream> solidInStream(inStreamSpec); + + // inStreamSpec->_reportArcProp = reportArcProp; + + inStreamSpec->Need_CTime = options.Need_CTime; + inStreamSpec->Need_ATime = options.Need_ATime; + inStreamSpec->Need_MTime = options.Need_MTime; + inStreamSpec->Need_Attrib = options.Need_Attrib; + // inStreamSpec->Need_Crc = options.Need_Crc; + inStreamSpec->Init(updateCallback, &indices[i], numSubFiles); unsigned startPackIndex = newDatabase.PackSizes.Size(); - UInt64 curFolderUnpackSize; - RINOK(encoder.Encode( + // UInt64 curFolderUnpackSize = totalSize; + // curFolderUnpackSize = (UInt64)(Int64)-1; // for debug + const UInt64 expectedDataSize = totalSize; + + // const unsigned folderIndex_New = newDatabase.Folders.Size(); + + RINOK(encoder.Encode1( EXTERNAL_CODECS_LOC_VARS solidInStream, // NULL, &inSizeForReduce, - newDatabase.Folders.AddNew(), newDatabase.CoderUnpackSizes, curFolderUnpackSize, - archive.SeqStream, newDatabase.PackSizes, progress)); + expectedDataSize, // expected size + newDatabase.Folders.AddNew(), + // newDatabase.CoderUnpackSizes, curFolderUnpackSize, + archive.SeqStream, newDatabase.PackSizes, progress)) if (!inStreamSpec->WasFinished()) return E_FAIL; + /* + if (inStreamSpec->Need_FolderCrc) + newDatabase.FolderUnpackCRCs.SetItem(folderIndex_New, + true, inStreamSpec->GetFolderCrc()); + */ + + const UInt64 curFolderUnpackSize = inStreamSpec->Get_TotalSize_for_Coder(); + encoder.Encode_Post(curFolderUnpackSize, newDatabase.CoderUnpackSizes); + + UInt64 packSize = 0; + // const UInt32 numStreams = newDatabase.PackSizes.Size() - startPackIndex; for (; startPackIndex < newDatabase.PackSizes.Size(); startPackIndex++) - lps->OutSize += newDatabase.PackSizes[startPackIndex]; + packSize += newDatabase.PackSizes[startPackIndex]; + lps->OutSize += packSize; - lps->InSize += curFolderUnpackSize; // for () // newDatabase.PackCRCsDefined.Add(false); // newDatabase.PackCRCs.Add(0); CNum numUnpackStreams = 0; UInt64 skippedSize = 0; - + UInt64 procSize = 0; + // unsigned numProcessedFiles = 0; + for (unsigned subIndex = 0; subIndex < numSubFiles; subIndex++) { const CUpdateItem &ui = updateItems[indices[i + subIndex]]; @@ -2367,13 +2745,13 @@ HRESULT Update( UString name; if (ui.NewProps) { - FromUpdateItemToFileItem(ui, file, file2); + UpdateItem_To_FileItem(ui, file, file2); name = ui.Name; } else { - GetFile(*db, ui.IndexInArchive, file, file2); - db->GetPath(ui.IndexInArchive, name); + GetFile(*db, (unsigned)ui.IndexInArchive, file, file2); + db->GetPath((unsigned)ui.IndexInArchive, name); } if (file2.IsAnti || file.IsDir) return E_FAIL; @@ -2384,18 +2762,21 @@ HRESULT Update( */ if (!inStreamSpec->Processed[subIndex]) { + // we don't add file here skippedSize += ui.Size; - continue; - // file.Name.AddAscii(".locked"); + continue; // comment it for debug + // name += ".locked"; // for debug } + // if (inStreamSpec->Need_Crc) file.Crc = inStreamSpec->CRCs[subIndex]; file.Size = inStreamSpec->Sizes[subIndex]; - // if (file.Size >= 0) // test purposes + procSize += file.Size; + // if (file.Size >= 0) // for debug: test purposes if (file.Size != 0) { - file.CrcDefined = true; + file.CrcDefined = true; // inStreamSpec->Need_Crc; file.HasStream = true; numUnpackStreams++; } @@ -2405,6 +2786,23 @@ HRESULT Update( file.HasStream = false; } + if (inStreamSpec->TimesDefined[subIndex]) + { + if (inStreamSpec->Need_CTime) + { file2.CTimeDefined = true; file2.CTime = inStreamSpec->CTimes[subIndex]; } + if (inStreamSpec->Need_ATime + // && !ui.ATime_WasReadByAnalysis + ) + { file2.ATimeDefined = true; file2.ATime = inStreamSpec->ATimes[subIndex]; } + if (inStreamSpec->Need_MTime) + { file2.MTimeDefined = true; file2.MTime = inStreamSpec->MTimes[subIndex]; } + if (inStreamSpec->Need_Attrib) + { + file2.AttribDefined = true; + file2.Attrib = inStreamSpec->Attribs[subIndex]; + } + } + /* file.Parent = ui.ParentFolderIndex; if (ui.TreeFolderIndex >= 0) @@ -2412,9 +2810,79 @@ HRESULT Update( if (totalSecureDataSize != 0) newDatabase.SecureIDs.Add(ui.SecureIndex); */ + /* + if (reportArcProp) + { + RINOK(ReportItemProps(reportArcProp, ui.IndexInClient, file.Size, + file.CrcDefined ? &file.Crc : NULL)) + } + */ + + // numProcessedFiles++; newDatabase.AddFile(file, file2, name); } + /* + // for debug: + // we can write crc to folders area, if folder contains only one file + if (numUnpackStreams == 1 && numSubFiles == 1) + { + const CFileItem &file = newDatabase.Files.Back(); + if (file.CrcDefined) + newDatabase.FolderUnpackCRCs.SetItem(folderIndex_New, true, file.Crc); + } + */ + + /* + // it's optional check to ensure that sizes are correct + if (inStreamSpec->TotalSize_for_Coder != curFolderUnpackSize) + return E_FAIL; + */ + // if (inStreamSpec->AlignLog == 0) + { + if (procSize != curFolderUnpackSize) + return E_FAIL; + } + // else + { + /* + { + const CFolder &old = newDatabase.Folders.Back(); + CFolder &folder = newDatabase.Folders.AddNew(); + { + const unsigned numBonds = old.Bonds.Size(); + folder.Bonds.SetSize(numBonds + 1); + for (unsigned k = 0; k < numBonds; k++) + folder.Bonds[k] = old.Bonds[k]; + CBond &bond = folder.Bonds[numBonds]; + bond.PackIndex = 0; + bond.UnpackIndex = 0; + } + { + const unsigned numCoders = old.Coders.Size(); + folder.Coders.SetSize(numCoders + 1); + for (unsigned k = 0; k < numCoders; k++) + folder.Coders[k] = old.Coders[k]; + CCoderInfo &cod = folder.Coders[numCoders]; + cod.Props.Alloc(1); + cod.Props[0] = (Byte)inStreamSpec->AlignLog; + cod.NumStreams = 1; + } + { + const unsigned numPackStreams = old.Coders.Size(); + folder.Coders.SetSize(numPackStreams); + for (unsigned k = 0; k < numPackStreams; k++) + folder.PackStreams[k] = old.PackStreams[k]; + } + } + newDatabase.Folders.Delete(newDatabase.Folders.Size() - 2); + */ + } + + + lps->InSize += procSize; + // lps->InSize += curFolderUnpackSize; + // numUnpackStreams = 0 is very bad case for locked files // v3.13 doesn't understand it. newDatabase.NumUnpackStreamsVector.Add(numUnpackStreams); @@ -2423,12 +2891,50 @@ HRESULT Update( if (skippedSize != 0 && complexity >= skippedSize) { complexity -= skippedSize; - RINOK(updateCallback->SetTotal(complexity)); + RINOK(updateCallback->SetTotal(complexity)) } + + /* + if (reportArcProp) + { + PROPVARIANT prop; + prop.vt = VT_EMPTY; + prop.wReserved1 = 0; + { + NWindows::NCOM::PropVarEm_Set_UInt32(&prop, numProcessedFiles); + RINOK(reportArcProp->ReportProp( + NEventIndexType::kBlockIndex, (UInt32)folderIndex, kpidNumSubFiles, &prop)); + } + { + NWindows::NCOM::PropVarEm_Set_UInt64(&prop, curFolderUnpackSize); + RINOK(reportArcProp->ReportProp( + NEventIndexType::kBlockIndex, (UInt32)folderIndex, kpidSize, &prop)); + } + { + NWindows::NCOM::PropVarEm_Set_UInt64(&prop, packSize); + RINOK(reportArcProp->ReportProp( + NEventIndexType::kBlockIndex, (UInt32)folderIndex, kpidPackSize, &prop)); + } + { + NWindows::NCOM::PropVarEm_Set_UInt32(&prop, numStreams); + RINOK(reportArcProp->ReportProp( + NEventIndexType::kBlockIndex, (UInt32)folderIndex, kpidNumStreams, &prop)); + } + RINOK(reportArcProp->ReportFinished(NEventIndexType::kBlockIndex, (UInt32)folderIndex, NUpdate::NOperationResult::kOK)); + } + */ + /* + if (opCallback) + { + RINOK(opCallback->ReportOperation( + NEventIndexType::kBlockIndex, (UInt32)folderIndex, + NUpdateNotifyOp::kOpFinished)); + } + */ } } - RINOK(lps->SetCur()); + RINOK(lps->SetCur()) /* fileIndexToUpdateIndexMap.ClearAndFree(); @@ -2458,10 +2964,26 @@ HRESULT Update( } } */ + + { + const unsigned numFolders = newDatabase.Folders.Size(); + if (newDatabase.NumUnpackStreamsVector.Size() != numFolders + || newDatabase.FolderUnpackCRCs.Defs.Size() > numFolders) + return E_FAIL; + newDatabase.FolderUnpackCRCs.if_NonEmpty_FillResedue_with_false(numFolders); + } + + updateItems.ClearAndFree(); newDatabase.ReserveDown(); if (opCallback) - RINOK(opCallback->ReportOperation(NEventIndexType::kNoIndex, (UInt32)(Int32)-1, NUpdateNotifyOp::kHeader)); + RINOK(opCallback->ReportOperation(NEventIndexType::kNoIndex, (UInt32)(Int32)-1, NUpdateNotifyOp::kHeader)) + + RINOK(archive.WriteDatabase(EXTERNAL_CODECS_LOC_VARS + newDatabase, options.HeaderMethod, options.HeaderOptions)) + + if (v_StreamSetRestriction) + RINOK(v_StreamSetRestriction->SetRestriction(0, 0)) return S_OK; } diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/7zUpdate.h b/3rdparty/lzma/CPP/7zip/Archive/7z/7zUpdate.h index a7abf779a61..de4117af266 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/7z/7zUpdate.h +++ b/3rdparty/lzma/CPP/7zip/Archive/7z/7zUpdate.h @@ -1,7 +1,7 @@ // 7zUpdate.h -#ifndef __7Z_UPDATE_H -#define __7Z_UPDATE_H +#ifndef ZIP7_INC_7Z_UPDATE_H +#define ZIP7_INC_7Z_UPDATE_H #include "../IArchive.h" @@ -9,7 +9,6 @@ #include "7zCompressionMode.h" #include "7zIn.h" -#include "7zOut.h" namespace NArchive { namespace N7z { @@ -31,7 +30,7 @@ struct CTreeFolder struct CUpdateItem { int IndexInArchive; - int IndexInClient; + unsigned IndexInClient; UInt64 CTime; UInt64 ATime; @@ -62,6 +61,8 @@ struct CUpdateItem bool ATimeDefined; bool MTimeDefined; + // bool ATime_WasReadByAnalysis; + // int SecureIndex; // 0 means (no_security) bool HasStream() const { return !IsDir && !IsAnti && Size != 0; } @@ -76,6 +77,7 @@ struct CUpdateItem CTimeDefined(false), ATimeDefined(false), MTimeDefined(false) + // , ATime_WasReadByAnalysis(false) // SecureIndex(0) {} void SetDirStatusFromAttrib() { IsDir = ((Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0); } @@ -92,8 +94,6 @@ struct CUpdateOptions bool MaxFilter; // use BCJ2 filter instead of BCJ int AnalysisLevel; - CHeaderOptions HeaderOptions; - UInt64 NumSolidFiles; UInt64 NumSolidBytes; bool SolidExtension; @@ -103,6 +103,14 @@ struct CUpdateOptions bool RemoveSfxBlock; bool MultiThreadMixer; + bool Need_CTime; + bool Need_ATime; + bool Need_MTime; + bool Need_Attrib; + // bool Need_Crc; + + CHeaderOptions HeaderOptions; + CUpdateOptions(): Method(NULL), HeaderMethod(NULL), @@ -114,7 +122,12 @@ struct CUpdateOptions SolidExtension(false), UseTypeSorting(true), RemoveSfxBlock(false), - MultiThreadMixer(true) + MultiThreadMixer(true), + Need_CTime(false), + Need_ATime(false), + Need_MTime(false), + Need_Attrib(false) + // , Need_Crc(true) {} }; @@ -122,18 +135,12 @@ HRESULT Update( DECL_EXTERNAL_CODECS_LOC_VARS IInStream *inStream, const CDbEx *db, - const CObjectVector<CUpdateItem> &updateItems, + CObjectVector<CUpdateItem> &updateItems, // const CObjectVector<CTreeFolder> &treeFolders, // treeFolders[0] is root // const CUniqBlocks &secureBlocks, - COutArchive &archive, - CArchiveDatabaseOut &newDatabase, ISequentialOutStream *seqOutStream, IArchiveUpdateCallback *updateCallback, - const CUpdateOptions &options - #ifndef _NO_CRYPTO - , ICryptoGetTextPassword *getDecoderPassword - #endif - ); + const CUpdateOptions &options); }} #endif diff --git a/3rdparty/lzma/CPP/7zip/Archive/7z/StdAfx.h b/3rdparty/lzma/CPP/7zip/Archive/7z/StdAfx.h index 2854ff3e935..035267ccd02 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/7z/StdAfx.h +++ b/3rdparty/lzma/CPP/7zip/Archive/7z/StdAfx.h @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../../Common/Common.h" #endif diff --git a/3rdparty/lzma/CPP/7zip/Archive/Archive.def b/3rdparty/lzma/CPP/7zip/Archive/Archive.def index 145516d7970..2ed624623b8 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/Archive.def +++ b/3rdparty/lzma/CPP/7zip/Archive/Archive.def @@ -10,3 +10,5 @@ EXPORTS SetLargePageMode PRIVATE SetCaseSensitive PRIVATE + + GetModuleProp PRIVATE diff --git a/3rdparty/lzma/CPP/7zip/Archive/Archive2.def b/3rdparty/lzma/CPP/7zip/Archive/Archive2.def index c7582742198..f891ad3b877 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/Archive2.def +++ b/3rdparty/lzma/CPP/7zip/Archive/Archive2.def @@ -17,3 +17,5 @@ EXPORTS SetLargePageMode PRIVATE SetCaseSensitive PRIVATE + + GetModuleProp PRIVATE diff --git a/3rdparty/lzma/CPP/7zip/Archive/ArchiveExports.cpp b/3rdparty/lzma/CPP/7zip/Archive/ArchiveExports.cpp index 28e9946d5f6..4735fcfff04 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/ArchiveExports.cpp +++ b/3rdparty/lzma/CPP/7zip/Archive/ArchiveExports.cpp @@ -10,7 +10,7 @@ #include "../Common/RegisterArc.h" -static const unsigned kNumArcsMax = 64; +static const unsigned kNumArcsMax = 72; static unsigned g_NumArcs = 0; static unsigned g_DefaultArcIndex = 0; static const CArcInfo *g_Arcs[kNumArcsMax]; @@ -24,9 +24,10 @@ void RegisterArc(const CArcInfo *arcInfo) throw() g_DefaultArcIndex = g_NumArcs; g_Arcs[g_NumArcs++] = arcInfo; } + // else throw 1; } -DEFINE_GUID(CLSID_CArchiveHandler, +Z7_DEFINE_GUID(CLSID_CArchiveHandler, k_7zip_GUID_Data1, k_7zip_GUID_Data2, k_7zip_GUID_Data3_Common, @@ -36,7 +37,7 @@ DEFINE_GUID(CLSID_CArchiveHandler, static inline HRESULT SetPropStrFromBin(const char *s, unsigned size, PROPVARIANT *value) { - if ((value->bstrVal = ::SysAllocStringByteLen(s, size)) != 0) + if ((value->bstrVal = ::SysAllocStringByteLen(s, size)) != NULL) value->vt = VT_BSTR; return S_OK; } @@ -46,28 +47,29 @@ static inline HRESULT SetPropGUID(const GUID &guid, PROPVARIANT *value) return SetPropStrFromBin((const char *)&guid, sizeof(guid), value); } -int FindFormatCalssId(const GUID *clsid) +static int FindFormatCalssId(const GUID *clsid) { GUID cls = *clsid; CLS_ARC_ID_ITEM(cls) = 0; if (cls != CLSID_CArchiveHandler) return -1; - Byte id = CLS_ARC_ID_ITEM(*clsid); + const Byte id = CLS_ARC_ID_ITEM(*clsid); for (unsigned i = 0; i < g_NumArcs; i++) if (g_Arcs[i]->Id == id) return (int)i; return -1; } +STDAPI CreateArchiver(const GUID *clsid, const GUID *iid, void **outObject); STDAPI CreateArchiver(const GUID *clsid, const GUID *iid, void **outObject) { COM_TRY_BEGIN { - int needIn = (*iid == IID_IInArchive); - int needOut = (*iid == IID_IOutArchive); + const int needIn = (*iid == IID_IInArchive); + const int needOut = (*iid == IID_IOutArchive); if (!needIn && !needOut) return E_NOINTERFACE; - int formatIndex = FindFormatCalssId(clsid); + const int formatIndex = FindFormatCalssId(clsid); if (formatIndex < 0) return CLASS_E_CLASSNOTAVAILABLE; @@ -89,6 +91,7 @@ STDAPI CreateArchiver(const GUID *clsid, const GUID *iid, void **outObject) return S_OK; } +STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value); STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value) { COM_TRY_BEGIN @@ -113,6 +116,7 @@ STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value case NArchive::NHandlerPropID::kAltStreams: prop = ((arc.Flags & NArcInfoFlags::kAltStreams) != 0); break; case NArchive::NHandlerPropID::kNtSecure: prop = ((arc.Flags & NArcInfoFlags::kNtSecure) != 0); break; case NArchive::NHandlerPropID::kFlags: prop = (UInt32)arc.Flags; break; + case NArchive::NHandlerPropID::kTimeFlags: prop = (UInt32)arc.TimeFlags; break; case NArchive::NHandlerPropID::kSignatureOffset: prop = (UInt32)arc.SignatureOffset; break; // case NArchive::NHandlerPropID::kVersion: prop = (UInt32)MY_VER_MIX; break; @@ -130,17 +134,20 @@ STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value COM_TRY_END } +STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value); STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value) { return GetHandlerProperty2(g_DefaultArcIndex, propID, value); } +STDAPI GetNumberOfFormats(UINT32 *numFormats); STDAPI GetNumberOfFormats(UINT32 *numFormats) { *numFormats = g_NumArcs; return S_OK; } +STDAPI GetIsArc(UInt32 formatIndex, Func_IsArc *isArc); STDAPI GetIsArc(UInt32 formatIndex, Func_IsArc *isArc) { *isArc = NULL; diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2.cpp b/3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2.cpp index 41b5805c115..b6ddeb839c9 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2.cpp +++ b/3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2.cpp @@ -6,7 +6,7 @@ #ifdef USE_MIXER_ST -STDMETHODIMP CSequentialInStreamCalcSize::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CSequentialInStreamCalcSize::Read(void *data, UInt32 size, UInt32 *processedSize)) { UInt32 realProcessed = 0; HRESULT result = S_OK; @@ -21,7 +21,7 @@ STDMETHODIMP CSequentialInStreamCalcSize::Read(void *data, UInt32 size, UInt32 * } -STDMETHODIMP COutStreamCalcSize::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(COutStreamCalcSize::Write(const void *data, UInt32 size, UInt32 *processedSize)) { HRESULT result = S_OK; if (_stream) @@ -32,7 +32,7 @@ STDMETHODIMP COutStreamCalcSize::Write(const void *data, UInt32 size, UInt32 *pr return result; } -STDMETHODIMP COutStreamCalcSize::OutStreamFinish() +Z7_COM7F_IMF(COutStreamCalcSize::OutStreamFinish()) { HRESULT result = S_OK; if (_stream) @@ -60,6 +60,63 @@ static void BoolVector_Fill_False(CBoolVector &v, unsigned size) p[i] = false; } + +HRESULT CCoder::CheckDataAfterEnd(bool &dataAfterEnd_Error /* , bool &InternalPackSizeError */) const +{ + if (Coder) + { + if (PackSizePointers.IsEmpty() || !PackSizePointers[0]) + return S_OK; + CMyComPtr<ICompressGetInStreamProcessedSize> getInStreamProcessedSize; + Coder.QueryInterface(IID_ICompressGetInStreamProcessedSize, (void **)&getInStreamProcessedSize); + // if (!getInStreamProcessedSize) return E_FAIL; + if (getInStreamProcessedSize) + { + UInt64 processed; + RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(&processed)) + if (processed != (UInt64)(Int64)-1) + { + const UInt64 size = PackSizes[0]; + if (processed < size && Finish) + dataAfterEnd_Error = true; + if (processed > size) + { + // InternalPackSizeError = true; + // return S_FALSE; + } + } + } + } + else if (Coder2) + { + CMyComPtr<ICompressGetInStreamProcessedSize2> getInStreamProcessedSize2; + Coder2.QueryInterface(IID_ICompressGetInStreamProcessedSize2, (void **)&getInStreamProcessedSize2); + if (getInStreamProcessedSize2) + FOR_VECTOR (i, PackSizePointers) + { + if (!PackSizePointers[i]) + continue; + UInt64 processed; + RINOK(getInStreamProcessedSize2->GetInStreamProcessedSize2(i, &processed)) + if (processed != (UInt64)(Int64)-1) + { + const UInt64 size = PackSizes[i]; + if (processed < size && Finish) + dataAfterEnd_Error = true; + else if (processed > size) + { + // InternalPackSizeError = true; + // return S_FALSE; + } + } + } + } + + return S_OK; +} + + + class CBondsChecks { CBoolVector _coderUsed; @@ -80,7 +137,7 @@ bool CBondsChecks::CheckCoder(unsigned coderIndex) return false; _coderUsed[coderIndex] = true; - UInt32 start = BindInfo->Coder_to_Stream[coderIndex]; + const UInt32 start = BindInfo->Coder_to_Stream[coderIndex]; for (unsigned i = 0; i < coder.NumStreams; i++) { @@ -89,10 +146,10 @@ bool CBondsChecks::CheckCoder(unsigned coderIndex) if (BindInfo->IsStream_in_PackStreams(ind)) continue; - int bond = BindInfo->FindBond_for_PackStream(ind); + const int bond = BindInfo->FindBond_for_PackStream(ind); if (bond < 0) return false; - if (!CheckCoder(BindInfo->Bonds[bond].UnpackIndex)) + if (!CheckCoder(BindInfo->Bonds[(unsigned)bond].UnpackIndex)) return false; } @@ -151,8 +208,10 @@ bool CBindInfo::CalcMapsAndCheck() } -void CCoder::SetCoderInfo(const UInt64 *unpackSize, const UInt64 * const *packSizes) +void CCoder::SetCoderInfo(const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish) { + Finish = finish; + if (unpackSize) { UnpackSize = *unpackSize; @@ -187,15 +246,15 @@ bool CMixer::Is_UnpackSize_Correct_for_Coder(UInt32 coderIndex) if (coderIndex == _bi.UnpackCoder) return true; - int bond = _bi.FindBond_for_UnpackStream(coderIndex); + const int bond = _bi.FindBond_for_UnpackStream(coderIndex); if (bond < 0) throw 20150213; /* UInt32 coderIndex, coderStreamIndex; - _bi.GetCoder_for_Stream(_bi.Bonds[bond].PackIndex, coderIndex, coderStreamIndex); + _bi.GetCoder_for_Stream(_bi.Bonds[(unsigned)bond].PackIndex, coderIndex, coderStreamIndex); */ - UInt32 nextCoder = _bi.Stream_to_Coder[_bi.Bonds[bond].PackIndex]; + const UInt32 nextCoder = _bi.Stream_to_Coder[_bi.Bonds[(unsigned)bond].PackIndex]; if (!IsFilter_Vector[nextCoder]) return false; @@ -208,11 +267,11 @@ bool CMixer::Is_PackSize_Correct_for_Stream(UInt32 streamIndex) if (_bi.IsStream_in_PackStreams(streamIndex)) return true; - int bond = _bi.FindBond_for_PackStream(streamIndex); + const int bond = _bi.FindBond_for_PackStream(streamIndex); if (bond < 0) throw 20150213; - UInt32 nextCoder = _bi.Bonds[bond].UnpackIndex; + const UInt32 nextCoder = _bi.Bonds[(unsigned)bond].UnpackIndex; if (!IsFilter_Vector[nextCoder]) return false; @@ -222,8 +281,8 @@ bool CMixer::Is_PackSize_Correct_for_Stream(UInt32 streamIndex) bool CMixer::Is_PackSize_Correct_for_Coder(UInt32 coderIndex) { - UInt32 startIndex = _bi.Coder_to_Stream[coderIndex]; - UInt32 numStreams = _bi.Coders[coderIndex].NumStreams; + const UInt32 startIndex = _bi.Coder_to_Stream[coderIndex]; + const UInt32 numStreams = _bi.Coders[coderIndex].NumStreams; for (UInt32 i = 0; i < numStreams; i++) if (!Is_PackSize_Correct_for_Stream(startIndex + i)) return false; @@ -234,19 +293,19 @@ bool CMixer::IsThere_ExternalCoder_in_PackTree(UInt32 coderIndex) { if (IsExternal_Vector[coderIndex]) return true; - UInt32 startIndex = _bi.Coder_to_Stream[coderIndex]; - UInt32 numStreams = _bi.Coders[coderIndex].NumStreams; + const UInt32 startIndex = _bi.Coder_to_Stream[coderIndex]; + const UInt32 numStreams = _bi.Coders[coderIndex].NumStreams; for (UInt32 i = 0; i < numStreams; i++) { - UInt32 si = startIndex + i; + const UInt32 si = startIndex + i; if (_bi.IsStream_in_PackStreams(si)) continue; - int bond = _bi.FindBond_for_PackStream(si); + const int bond = _bi.FindBond_for_PackStream(si); if (bond < 0) throw 20150213; - if (IsThere_ExternalCoder_in_PackTree(_bi.Bonds[bond].UnpackIndex)) + if (IsThere_ExternalCoder_in_PackTree(_bi.Bonds[(unsigned)bond].UnpackIndex)) return true; } return false; @@ -284,13 +343,11 @@ void CMixerST::AddCoder(const CCreatedCoder &cod) { IUnknown *unk = (cod.Coder ? (IUnknown *)cod.Coder : (IUnknown *)cod.Coder2); { - CMyComPtr<ISequentialInStream> s; - unk->QueryInterface(IID_ISequentialInStream, (void**)&s); + Z7_DECL_CMyComPtr_QI_FROM(ISequentialInStream, s, unk) c2.CanRead = (s != NULL); } { - CMyComPtr<ISequentialOutStream> s; - unk->QueryInterface(IID_ISequentialOutStream, (void**)&s); + Z7_DECL_CMyComPtr_QI_FROM(ISequentialOutStream, s, unk) c2.CanWrite = (s != NULL); } } @@ -301,7 +358,7 @@ CCoder &CMixerST::GetCoder(unsigned index) return _coders[index]; } -void CMixerST::ReInit() {} +HRESULT CMixerST::ReInit2() { return S_OK; } HRESULT CMixerST::GetInStream2( ISequentialInStream * const *inStreams, /* const UInt64 * const *inSizes, */ @@ -323,8 +380,8 @@ HRESULT CMixerST::GetInStream2( if (!seqInStream) return E_NOTIMPL; - UInt32 numInStreams = EncodeMode ? 1 : coder.NumStreams; - UInt32 startIndex = EncodeMode ? coderIndex : _bi.Coder_to_Stream[coderIndex]; + const UInt32 numInStreams = EncodeMode ? 1 : coder.NumStreams; + const UInt32 startIndex = EncodeMode ? coderIndex : _bi.Coder_to_Stream[coderIndex]; bool isSet = false; @@ -335,8 +392,8 @@ HRESULT CMixerST::GetInStream2( if (setStream) { CMyComPtr<ISequentialInStream> seqInStream2; - RINOK(GetInStream(inStreams, /* inSizes, */ startIndex + 0, &seqInStream2)); - RINOK(setStream->SetInStream(seqInStream2)); + RINOK(GetInStream(inStreams, /* inSizes, */ startIndex + 0, &seqInStream2)) + RINOK(setStream->SetInStream(seqInStream2)) isSet = true; } } @@ -351,8 +408,8 @@ HRESULT CMixerST::GetInStream2( for (UInt32 i = 0; i < numInStreams; i++) { CMyComPtr<ISequentialInStream> seqInStream2; - RINOK(GetInStream(inStreams, /* inSizes, */ startIndex + i, &seqInStream2)); - RINOK(setStream2->SetInStream2(i, seqInStream2)); + RINOK(GetInStream(inStreams, /* inSizes, */ startIndex + i, &seqInStream2)) + RINOK(setStream2->SetInStream2(i, seqInStream2)) } } @@ -385,18 +442,18 @@ HRESULT CMixerST::GetInStream( } } - int bond = FindBond_for_Stream( + const int bond = FindBond_for_Stream( true, // forInputStream inStreamIndex); if (bond < 0) return E_INVALIDARG; RINOK(GetInStream2(inStreams, /* inSizes, */ - _bi.Bonds[bond].Get_OutIndex(EncodeMode), &seqInStream)); + _bi.Bonds[(unsigned)bond].Get_OutIndex(EncodeMode), &seqInStream)) while (_binderStreams.Size() <= (unsigned)bond) _binderStreams.AddNew(); - CStBinderStream &bs = _binderStreams[bond]; + CStBinderStream &bs = _binderStreams[(unsigned)bond]; if (bs.StreamRef || bs.InStreamSpec) return E_NOTIMPL; @@ -439,13 +496,13 @@ HRESULT CMixerST::GetOutStream( } } - int bond = FindBond_for_Stream( + const int bond = FindBond_for_Stream( false, // forInputStream outStreamIndex); if (bond < 0) return E_INVALIDARG; - UInt32 inStreamIndex = _bi.Bonds[bond].Get_InIndex(EncodeMode); + const UInt32 inStreamIndex = _bi.Bonds[(unsigned)bond].Get_InIndex(EncodeMode); UInt32 coderIndex = inStreamIndex; UInt32 coderStreamIndex = 0; @@ -464,8 +521,8 @@ HRESULT CMixerST::GetOutStream( if (!seqOutStream) return E_NOTIMPL; - UInt32 numOutStreams = EncodeMode ? coder.NumStreams : 1; - UInt32 startIndex = EncodeMode ? _bi.Coder_to_Stream[coderIndex]: coderIndex; + const UInt32 numOutStreams = EncodeMode ? coder.NumStreams : 1; + const UInt32 startIndex = EncodeMode ? _bi.Coder_to_Stream[coderIndex]: coderIndex; bool isSet = false; @@ -476,8 +533,8 @@ HRESULT CMixerST::GetOutStream( if (setOutStream) { CMyComPtr<ISequentialOutStream> seqOutStream2; - RINOK(GetOutStream(outStreams, /* outSizes, */ startIndex + 0, &seqOutStream2)); - RINOK(setOutStream->SetOutStream(seqOutStream2)); + RINOK(GetOutStream(outStreams, /* outSizes, */ startIndex + 0, &seqOutStream2)) + RINOK(setOutStream->SetOutStream(seqOutStream2)) isSet = true; } } @@ -493,15 +550,15 @@ HRESULT CMixerST::GetOutStream( for (UInt32 i = 0; i < numOutStreams; i++) { CMyComPtr<ISequentialOutStream> seqOutStream2; - RINOK(GetOutStream(outStreams, startIndex + i, &seqOutStream2)); - RINOK(setStream2->SetOutStream2(i, seqOutStream2)); + RINOK(GetOutStream(outStreams, startIndex + i, &seqOutStream2)) + RINOK(setStream2->SetOutStream2(i, seqOutStream2)) } */ } while (_binderStreams.Size() <= (unsigned)bond) _binderStreams.AddNew(); - CStBinderStream &bs = _binderStreams[bond]; + CStBinderStream &bs = _binderStreams[(unsigned)bond]; if (bs.StreamRef || bs.OutStreamSpec) return E_NOTIMPL; @@ -551,13 +608,13 @@ HRESULT CMixerST::FinishStream(UInt32 streamIndex) return S_OK; } - int bond = FindBond_for_Stream( + const int bond = FindBond_for_Stream( false, // forInputStream streamIndex); if (bond < 0) return E_INVALIDARG; - UInt32 inStreamIndex = _bi.Bonds[bond].Get_InIndex(EncodeMode); + const UInt32 inStreamIndex = _bi.Bonds[(unsigned)bond].Get_InIndex(EncodeMode); UInt32 coderIndex = inStreamIndex; UInt32 coderStreamIndex = 0; @@ -580,8 +637,8 @@ HRESULT CMixerST::FinishCoder(UInt32 coderIndex) { CCoder &coder = _coders[coderIndex]; - UInt32 numOutStreams = EncodeMode ? coder.NumStreams : 1; - UInt32 startIndex = EncodeMode ? _bi.Coder_to_Stream[coderIndex]: coderIndex; + const UInt32 numOutStreams = EncodeMode ? coder.NumStreams : 1; + const UInt32 startIndex = EncodeMode ? _bi.Coder_to_Stream[coderIndex]: coderIndex; HRESULT res = S_OK; for (unsigned i = 0; i < numOutStreams; i++) @@ -595,7 +652,7 @@ void CMixerST::SelectMainCoder(bool useFirst) unsigned ci = _bi.UnpackCoder; int firstNonFilter = -1; - int firstAllowed = ci; + unsigned firstAllowed = ci; for (;;) { @@ -612,10 +669,10 @@ void CMixerST::SelectMainCoder(bool useFirst) if (coder.NumStreams != 1) break; - UInt32 st = _bi.Coder_to_Stream[ci]; + const UInt32 st = _bi.Coder_to_Stream[ci]; if (_bi.IsStream_in_PackStreams(st)) break; - int bond = _bi.FindBond_for_PackStream(st); + const int bond = _bi.FindBond_for_PackStream(st); if (bond < 0) throw 20150213; @@ -623,15 +680,15 @@ void CMixerST::SelectMainCoder(bool useFirst) break; if (firstNonFilter == -1 && !IsFilter_Vector[ci]) - firstNonFilter = ci; + firstNonFilter = (int)ci; - ci = _bi.Bonds[bond].UnpackIndex; + ci = _bi.Bonds[(unsigned)bond].UnpackIndex; } if (useFirst) ci = firstAllowed; else if (firstNonFilter >= 0) - ci = firstNonFilter; + ci = (unsigned)firstNonFilter; MainCoderIndex = ci; } @@ -640,35 +697,39 @@ void CMixerST::SelectMainCoder(bool useFirst) HRESULT CMixerST::Code( ISequentialInStream * const *inStreams, ISequentialOutStream * const *outStreams, - ICompressProgressInfo *progress) + ICompressProgressInfo *progress, + bool &dataAfterEnd_Error) { + // InternalPackSizeError = false; + dataAfterEnd_Error = false; + _binderStreams.Clear(); - unsigned ci = MainCoderIndex; + const unsigned ci = MainCoderIndex; const CCoder &mainCoder = _coders[MainCoderIndex]; CObjectVector< CMyComPtr<ISequentialInStream> > seqInStreams; CObjectVector< CMyComPtr<ISequentialOutStream> > seqOutStreams; - UInt32 numInStreams = EncodeMode ? 1 : mainCoder.NumStreams; - UInt32 numOutStreams = !EncodeMode ? 1 : mainCoder.NumStreams; + const UInt32 numInStreams = EncodeMode ? 1 : mainCoder.NumStreams; + const UInt32 numOutStreams = !EncodeMode ? 1 : mainCoder.NumStreams; - UInt32 startInIndex = EncodeMode ? ci : _bi.Coder_to_Stream[ci]; - UInt32 startOutIndex = !EncodeMode ? ci : _bi.Coder_to_Stream[ci]; + const UInt32 startInIndex = EncodeMode ? ci : _bi.Coder_to_Stream[ci]; + const UInt32 startOutIndex = !EncodeMode ? ci : _bi.Coder_to_Stream[ci]; UInt32 i; for (i = 0; i < numInStreams; i++) { CMyComPtr<ISequentialInStream> seqInStream; - RINOK(GetInStream(inStreams, /* inSizes, */ startInIndex + i, &seqInStream)); + RINOK(GetInStream(inStreams, /* inSizes, */ startInIndex + i, &seqInStream)) seqInStreams.Add(seqInStream); } for (i = 0; i < numOutStreams; i++) { CMyComPtr<ISequentialOutStream> seqOutStream; - RINOK(GetOutStream(outStreams, /* outSizes, */ startOutIndex + i, &seqOutStream)); + RINOK(GetOutStream(outStreams, /* outSizes, */ startOutIndex + i, &seqOutStream)) seqOutStreams.Add(seqOutStream); } @@ -692,15 +753,19 @@ HRESULT CMixerST::Code( CMyComPtr<ICompressInitEncoder> initEncoder; coder.QueryInterface(IID_ICompressInitEncoder, (void **)&initEncoder); if (initEncoder) - RINOK(initEncoder->InitEncoder()); + { + RINOK(initEncoder->InitEncoder()) + } } else { CMyComPtr<ICompressSetOutStreamSize> setOutStreamSize; coder.QueryInterface(IID_ICompressSetOutStreamSize, (void **)&setOutStreamSize); if (setOutStreamSize) + { RINOK(setOutStreamSize->SetOutStreamSize( - EncodeMode ? coder.PackSizePointers[0] : coder.UnpackSizePointer)); + EncodeMode ? coder.PackSizePointers[0] : coder.UnpackSizePointer)) + } } } @@ -742,7 +807,16 @@ HRESULT CMixerST::Code( if (res == k_My_HRESULT_WritingWasCut) res = S_OK; - return res; + + if (res != S_OK) + return res; + + for (i = 0; i < _coders.Size(); i++) + { + RINOK(_coders[i].CheckDataAfterEnd(dataAfterEnd_Error /*, InternalPackSizeError */)) + } + + return S_OK; } @@ -762,7 +836,7 @@ HRESULT CMixerST::GetMainUnpackStream( coder.QueryInterface(IID_ICompressSetOutStreamSize, (void **)&setOutStreamSize); if (setOutStreamSize) { - RINOK(setOutStreamSize->SetOutStreamSize(coder.UnpackSizePointer)); + RINOK(setOutStreamSize->SetOutStreamSize(coder.UnpackSizePointer)) } } @@ -847,7 +921,8 @@ HRESULT CMixerMT::SetBindInfo(const CBindInfo &bindInfo) _streamBinders.Clear(); FOR_VECTOR (i, _bi.Bonds) { - RINOK(_streamBinders.AddNew().CreateEvents()); + // RINOK(_streamBinders.AddNew().CreateEvents()) + _streamBinders.AddNew(); } return S_OK; } @@ -869,10 +944,13 @@ CCoder &CMixerMT::GetCoder(unsigned index) return _coders[index]; } -void CMixerMT::ReInit() +HRESULT CMixerMT::ReInit2() { FOR_VECTOR (i, _streamBinders) - _streamBinders[i].ReInit(); + { + RINOK(_streamBinders[i].Create_ReInit()) + } + return S_OK; } void CMixerMT::SelectMainCoder(bool useFirst) @@ -890,10 +968,10 @@ void CMixerMT::SelectMainCoder(bool useFirst) UInt32 st = _bi.Coder_to_Stream[ci]; if (_bi.IsStream_in_PackStreams(st)) break; - int bond = _bi.FindBond_for_PackStream(st); + const int bond = _bi.FindBond_for_PackStream(st); if (bond < 0) throw 20150213; - ci = _bi.Bonds[bond].UnpackIndex; + ci = _bi.Bonds[(unsigned)bond].UnpackIndex; } MainCoderIndex = ci; @@ -910,8 +988,8 @@ HRESULT CMixerMT::Init(ISequentialInStream * const *inStreams, ISequentialOutStr UInt32 j; - unsigned numInStreams = EncodeMode ? 1 : csi.NumStreams; - unsigned numOutStreams = EncodeMode ? csi.NumStreams : 1; + const unsigned numInStreams = EncodeMode ? 1 : csi.NumStreams; + const unsigned numOutStreams = EncodeMode ? csi.NumStreams : 1; coderInfo.InStreams.Clear(); for (j = 0; j < numInStreams; j++) @@ -940,9 +1018,9 @@ HRESULT CMixerMT::Init(ISequentialInStream * const *inStreams, ISequentialOutStr outCoderStreamIndex = EncodeMode ? coderStreamIndex : 0; } - _streamBinders[i].CreateStreams( - &_coders[inCoderIndex].InStreams[inCoderStreamIndex], - &_coders[outCoderIndex].OutStreams[outCoderStreamIndex]); + _streamBinders[i].CreateStreams2( + _coders[inCoderIndex].InStreams[inCoderStreamIndex], + _coders[outCoderIndex].OutStreams[outCoderStreamIndex]); CMyComPtr<ICompressSetBufSize> inSetSize, outSetSize; _coders[inCoderIndex].QueryInterface(IID_ICompressSetBufSize, (void **)&inSetSize); @@ -988,29 +1066,46 @@ HRESULT CMixerMT::ReturnIfError(HRESULT code) HRESULT CMixerMT::Code( ISequentialInStream * const *inStreams, ISequentialOutStream * const *outStreams, - ICompressProgressInfo *progress) + ICompressProgressInfo *progress, + bool &dataAfterEnd_Error) { + // InternalPackSizeError = false; + dataAfterEnd_Error = false; + Init(inStreams, outStreams); unsigned i; for (i = 0; i < _coders.Size(); i++) if (i != MainCoderIndex) { - RINOK(_coders[i].Create()); + const WRes wres = _coders[i].Create(); + if (wres != 0) + return HRESULT_FROM_WIN32(wres); } for (i = 0; i < _coders.Size(); i++) if (i != MainCoderIndex) - _coders[i].Start(); + { + const WRes wres = _coders[i].Start(); + if (wres != 0) + return HRESULT_FROM_WIN32(wres); + } _coders[MainCoderIndex].Code(progress); + WRes wres = 0; for (i = 0; i < _coders.Size(); i++) if (i != MainCoderIndex) - _coders[i].WaitExecuteFinish(); + { + WRes wres2 = _coders[i].WaitExecuteFinish(); + if (wres == 0) + wres = wres2; + } + if (wres != 0) + return HRESULT_FROM_WIN32(wres); - RINOK(ReturnIfError(E_ABORT)); - RINOK(ReturnIfError(E_OUTOFMEMORY)); + RINOK(ReturnIfError(E_ABORT)) + RINOK(ReturnIfError(E_OUTOFMEMORY)) for (i = 0; i < _coders.Size(); i++) { @@ -1022,7 +1117,7 @@ HRESULT CMixerMT::Code( return result; } - RINOK(ReturnIfError(S_FALSE)); + RINOK(ReturnIfError(S_FALSE)) for (i = 0; i < _coders.Size(); i++) { @@ -1031,6 +1126,11 @@ HRESULT CMixerMT::Code( return result; } + for (i = 0; i < _coders.Size(); i++) + { + RINOK(_coders[i].CheckDataAfterEnd(dataAfterEnd_Error /* , InternalPackSizeError */)) + } + return S_OK; } diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2.h b/3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2.h index e63f2ff0efa..484a6089ad4 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2.h +++ b/3rdparty/lzma/CPP/7zip/Archive/Common/CoderMixer2.h @@ -1,7 +1,7 @@ // CoderMixer2.h -#ifndef __CODER_MIXER2_H -#define __CODER_MIXER2_H +#ifndef ZIP7_INC_CODER_MIXER2_H +#define ZIP7_INC_CODER_MIXER2_H #include "../../../Common/MyCom.h" #include "../../../Common/MyVector.h" @@ -10,11 +10,11 @@ #include "../../Common/CreateCoder.h" -#ifdef _7ZIP_ST +#ifdef Z7_ST #define USE_MIXER_ST #else #define USE_MIXER_MT - #ifndef _SFX + #ifndef Z7_SFX #define USE_MIXER_ST #endif #endif @@ -28,18 +28,13 @@ #ifdef USE_MIXER_ST -class CSequentialInStreamCalcSize: - public ISequentialInStream, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP1(ISequentialInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); -private: +Z7_CLASS_IMP_COM_1( + CSequentialInStreamCalcSize + , ISequentialInStream +) + bool _wasFinished; CMyComPtr<ISequentialInStream> _stream; UInt64 _size; - bool _wasFinished; public: void SetStream(ISequentialInStream *stream) { _stream = stream; } void Init() @@ -53,19 +48,14 @@ public: }; -class COutStreamCalcSize: - public ISequentialOutStream, - public IOutStreamFinish, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_2( + COutStreamCalcSize + , ISequentialOutStream + , IOutStreamFinish +) CMyComPtr<ISequentialOutStream> _stream; UInt64 _size; public: - MY_UNKNOWN_IMP2(ISequentialOutStream, IOutStreamFinish) - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(OutStreamFinish)(); - void SetStream(ISequentialOutStream *stream) { _stream = stream; } void ReleaseStream() { _stream.Release(); } void Init() { _size = 0; } @@ -107,7 +97,7 @@ struct CBindInfo { FOR_VECTOR (i, Bonds) if (Bonds[i].PackIndex == packStream) - return i; + return (int)i; return -1; } @@ -115,14 +105,14 @@ struct CBindInfo { FOR_VECTOR (i, Bonds) if (Bonds[i].UnpackIndex == unpackStream) - return i; + return (int)i; return -1; } bool SetUnpackCoder() { bool isOk = false; - FOR_VECTOR(i, Coders) + FOR_VECTOR (i, Coders) { if (FindBond_for_UnpackStream(i) < 0) { @@ -142,9 +132,9 @@ struct CBindInfo int FindStream_in_PackStreams(UInt32 streamIndex) const { - FOR_VECTOR(i, PackStreams) + FOR_VECTOR (i, PackStreams) if (PackStreams[i] == streamIndex) - return i; + return (int)i; return -1; } @@ -189,11 +179,12 @@ struct CBindInfo class CCoder { - CLASS_NO_COPY(CCoder); + Z7_CLASS_NO_COPY(CCoder) public: CMyComPtr<ICompressCoder> Coder; CMyComPtr<ICompressCoder2> Coder2; UInt32 NumStreams; + bool Finish; UInt64 UnpackSize; const UInt64 *UnpackSizePointer; @@ -201,9 +192,11 @@ public: CRecordVector<UInt64> PackSizes; CRecordVector<const UInt64 *> PackSizePointers; - CCoder() {} + CCoder(): Finish(false) {} + + void SetCoderInfo(const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish); - void SetCoderInfo(const UInt64 *unpackSize, const UInt64 * const *packSizes); + HRESULT CheckDataAfterEnd(bool &dataAfterEnd_Error /* , bool &InternalPackSizeError */) const; IUnknown *GetUnknown() const { @@ -239,11 +232,15 @@ protected: public: unsigned MainCoderIndex; + // bool InternalPackSizeError; + CMixer(bool encodeMode): EncodeMode(encodeMode), MainCoderIndex(0) + // , InternalPackSizeError(false) {} + virtual ~CMixer() {} /* Sequence of calling: @@ -272,12 +269,13 @@ public: virtual void AddCoder(const CCreatedCoder &cod) = 0; virtual CCoder &GetCoder(unsigned index) = 0; virtual void SelectMainCoder(bool useFirst) = 0; - virtual void ReInit() = 0; - virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes) = 0; + virtual HRESULT ReInit2() = 0; + virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish) = 0; virtual HRESULT Code( ISequentialInStream * const *inStreams, ISequentialOutStream * const *outStreams, - ICompressProgressInfo *progress) = 0; + ICompressProgressInfo *progress, + bool &dataAfterEnd_Error) = 0; virtual UInt64 GetBondStreamSize(unsigned bondIndex) const = 0; bool Is_UnpackSize_Correct_for_Coder(UInt32 coderIndex); @@ -314,6 +312,9 @@ class CMixerST: public CMixer, public CMyUnknownImp { + Z7_COM_UNKNOWN_IMP_0 + Z7_CLASS_NO_COPY(CMixerST) + HRESULT GetInStream2(ISequentialInStream * const *inStreams, /* const UInt64 * const *inSizes, */ UInt32 outStreamIndex, ISequentialInStream **inStreamRes); HRESULT GetInStream(ISequentialInStream * const *inStreams, /* const UInt64 * const *inSizes, */ @@ -329,22 +330,21 @@ public: CObjectVector<CStBinderStream> _binderStreams; - MY_UNKNOWN_IMP - CMixerST(bool encodeMode); - ~CMixerST(); - - virtual void AddCoder(const CCreatedCoder &cod); - virtual CCoder &GetCoder(unsigned index); - virtual void SelectMainCoder(bool useFirst); - virtual void ReInit(); - virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes) - { _coders[coderIndex].SetCoderInfo(unpackSize, packSizes); } + ~CMixerST() Z7_DESTRUCTOR_override; + + virtual void AddCoder(const CCreatedCoder &cod) Z7_override; + virtual CCoder &GetCoder(unsigned index) Z7_override; + virtual void SelectMainCoder(bool useFirst) Z7_override; + virtual HRESULT ReInit2() Z7_override; + virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish) Z7_override + { _coders[coderIndex].SetCoderInfo(unpackSize, packSizes, finish); } virtual HRESULT Code( ISequentialInStream * const *inStreams, ISequentialOutStream * const *outStreams, - ICompressProgressInfo *progress); - virtual UInt64 GetBondStreamSize(unsigned bondIndex) const; + ICompressProgressInfo *progress, + bool &dataAfterEnd_Error) Z7_override; + virtual UInt64 GetBondStreamSize(unsigned bondIndex) const Z7_override; HRESULT GetMainUnpackStream( ISequentialInStream * const *inStreams, @@ -360,12 +360,12 @@ public: class CCoderMT: public CCoder, public CVirtThread { - CLASS_NO_COPY(CCoderMT) + Z7_CLASS_NO_COPY(CCoderMT) CRecordVector<ISequentialInStream*> InStreamPointers; CRecordVector<ISequentialOutStream*> OutStreamPointers; private: - void Execute(); + virtual void Execute() Z7_override; public: bool EncodeMode; HRESULT Result; @@ -385,7 +385,7 @@ public: class CReleaser { - CLASS_NO_COPY(CReleaser) + Z7_CLASS_NO_COPY(CReleaser) CCoderMT &_c; public: CReleaser(CCoderMT &c): _c(c) {} @@ -393,7 +393,14 @@ public: }; CCoderMT(): EncodeMode(false) {} - ~CCoderMT() { CVirtThread::WaitThreadFinish(); } + ~CCoderMT() Z7_DESTRUCTOR_override + { + /* WaitThreadFinish() will be called in ~CVirtThread(). + But we need WaitThreadFinish() call before CCoder destructor, + and before destructors of this class members. + */ + CVirtThread::WaitThreadFinish(); + } void Code(ICompressProgressInfo *progress); }; @@ -404,28 +411,31 @@ class CMixerMT: public CMixer, public CMyUnknownImp { + Z7_COM_UNKNOWN_IMP_0 + Z7_CLASS_NO_COPY(CMixerMT) + CObjectVector<CStreamBinder> _streamBinders; HRESULT Init(ISequentialInStream * const *inStreams, ISequentialOutStream * const *outStreams); HRESULT ReturnIfError(HRESULT code); + // virtual ~CMixerMT() {} public: CObjectVector<CCoderMT> _coders; - MY_UNKNOWN_IMP - - virtual HRESULT SetBindInfo(const CBindInfo &bindInfo); - virtual void AddCoder(const CCreatedCoder &cod); - virtual CCoder &GetCoder(unsigned index); - virtual void SelectMainCoder(bool useFirst); - virtual void ReInit(); - virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes) - { _coders[coderIndex].SetCoderInfo(unpackSize, packSizes); } + virtual HRESULT SetBindInfo(const CBindInfo &bindInfo) Z7_override; + virtual void AddCoder(const CCreatedCoder &cod) Z7_override; + virtual CCoder &GetCoder(unsigned index) Z7_override; + virtual void SelectMainCoder(bool useFirst) Z7_override; + virtual HRESULT ReInit2() Z7_override; + virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish) Z7_override + { _coders[coderIndex].SetCoderInfo(unpackSize, packSizes, finish); } virtual HRESULT Code( ISequentialInStream * const *inStreams, ISequentialOutStream * const *outStreams, - ICompressProgressInfo *progress); - virtual UInt64 GetBondStreamSize(unsigned bondIndex) const; + ICompressProgressInfo *progress, + bool &dataAfterEnd_Error) Z7_override; + virtual UInt64 GetBondStreamSize(unsigned bondIndex) const Z7_override; CMixerMT(bool encodeMode): CMixer(encodeMode) {} }; diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/DummyOutStream.cpp b/3rdparty/lzma/CPP/7zip/Archive/Common/DummyOutStream.cpp index 7c4f54879de..f48c32f2fd7 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/Common/DummyOutStream.cpp +++ b/3rdparty/lzma/CPP/7zip/Archive/Common/DummyOutStream.cpp @@ -4,7 +4,7 @@ #include "DummyOutStream.h" -STDMETHODIMP CDummyOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CDummyOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { UInt32 realProcessedSize = size; HRESULT res = S_OK; diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/DummyOutStream.h b/3rdparty/lzma/CPP/7zip/Archive/Common/DummyOutStream.h index b5a51fc0755..f884e13c872 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/Common/DummyOutStream.h +++ b/3rdparty/lzma/CPP/7zip/Archive/Common/DummyOutStream.h @@ -1,24 +1,22 @@ // DummyOutStream.h -#ifndef __DUMMY_OUT_STREAM_H -#define __DUMMY_OUT_STREAM_H +#ifndef ZIP7_INC_DUMMY_OUT_STREAM_H +#define ZIP7_INC_DUMMY_OUT_STREAM_H #include "../../../Common/MyCom.h" #include "../../IStream.h" -class CDummyOutStream: - public ISequentialOutStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_NOQIB_1( + CDummyOutStream + , ISequentialOutStream +) CMyComPtr<ISequentialOutStream> _stream; UInt64 _size; public: void SetStream(ISequentialOutStream *outStream) { _stream = outStream; } void ReleaseStream() { _stream.Release(); } void Init() { _size = 0; } - MY_UNKNOWN_IMP - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); UInt64 GetSize() const { return _size; } }; diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/HandlerOut.cpp b/3rdparty/lzma/CPP/7zip/Archive/Common/HandlerOut.cpp index 30ca73bd023..17fed675b5d 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/Common/HandlerOut.cpp +++ b/3rdparty/lzma/CPP/7zip/Archive/Common/HandlerOut.cpp @@ -2,54 +2,175 @@ #include "StdAfx.h" -#ifndef _7ZIP_ST -#include "../../../Windows/System.h" -#endif +#include "../../../Common/StringToInt.h" #include "../Common/ParseProperties.h" #include "HandlerOut.h" -using namespace NWindows; - namespace NArchive { -static void SetMethodProp32(COneMethodInfo &m, PROPID propID, UInt32 value) +bool ParseSizeString(const wchar_t *s, const PROPVARIANT &prop, UInt64 percentsBase, UInt64 &res) +{ + if (*s == 0) + { + switch (prop.vt) + { + case VT_UI4: res = prop.ulVal; return true; + case VT_UI8: res = prop.uhVal.QuadPart; return true; + case VT_BSTR: + s = prop.bstrVal; + break; + default: return false; + } + } + else if (prop.vt != VT_EMPTY) + return false; + + bool percentMode = false; + { + const wchar_t c = *s; + if (MyCharLower_Ascii(c) == 'p') + { + percentMode = true; + s++; + } + } + + const wchar_t *end; + const UInt64 v = ConvertStringToUInt64(s, &end); + if (s == end) + return false; + const wchar_t c = *end; + + if (percentMode) + { + if (c != 0) + return false; + res = Calc_From_Val_Percents(percentsBase, v); + return true; + } + + if (c == 0) + { + res = v; + return true; + } + if (end[1] != 0) + return false; + + if (c == '%') + { + res = Calc_From_Val_Percents(percentsBase, v); + return true; + } + + unsigned numBits; + switch (MyCharLower_Ascii(c)) + { + case 'b': numBits = 0; break; + case 'k': numBits = 10; break; + case 'm': numBits = 20; break; + case 'g': numBits = 30; break; + case 't': numBits = 40; break; + default: return false; + } + const UInt64 val2 = v << numBits; + if ((val2 >> numBits) != v) + return false; + res = val2; + return true; +} + +bool CCommonMethodProps::SetCommonProperty(const UString &name, const PROPVARIANT &value, HRESULT &hres) +{ + hres = S_OK; + + if (name.IsPrefixedBy_Ascii_NoCase("mt")) + { + #ifndef Z7_ST + _numThreads = _numProcessors; + _numThreads_WasForced = false; + hres = ParseMtProp2(name.Ptr(2), value, _numThreads, _numThreads_WasForced); + // "mt" means "_numThreads_WasForced = false" here + #endif + return true; + } + + if (name.IsPrefixedBy_Ascii_NoCase("memuse")) + { + UInt64 v; + if (!ParseSizeString(name.Ptr(6), value, _memAvail, v)) + hres = E_INVALIDARG; + _memUsage_Decompress = v; + _memUsage_Compress = v; + _memUsage_WasSet = true; + return true; + } + + return false; +} + + +#ifndef Z7_EXTRACT_ONLY + +static void SetMethodProp32(CMethodProps &m, PROPID propID, UInt32 value) { if (m.FindProp(propID) < 0) m.AddProp32(propID, value); } -void CMultiMethodProps::SetGlobalLevelAndThreads(COneMethodInfo &oneMethodInfo - #ifndef _7ZIP_ST - , UInt32 numThreads - #endif - ) +void CMultiMethodProps::SetGlobalLevelTo(COneMethodInfo &oneMethodInfo) const { UInt32 level = _level; if (level != (UInt32)(Int32)-1) SetMethodProp32(oneMethodInfo, NCoderPropID::kLevel, (UInt32)level); - - #ifndef _7ZIP_ST +} + +#ifndef Z7_ST + +static void SetMethodProp32_Replace(CMethodProps &m, PROPID propID, UInt32 value) +{ + const int i = m.FindProp(propID); + if (i >= 0) + { + NWindows::NCOM::CPropVariant &val = m.Props[(unsigned)i].Value; + val = (UInt32)value; + return; + } + m.AddProp32(propID, value); +} + +void CMultiMethodProps::SetMethodThreadsTo_IfNotFinded(CMethodProps &oneMethodInfo, UInt32 numThreads) +{ SetMethodProp32(oneMethodInfo, NCoderPropID::kNumThreads, numThreads); - #endif } -void CMultiMethodProps::Init() +void CMultiMethodProps::SetMethodThreadsTo_Replace(CMethodProps &oneMethodInfo, UInt32 numThreads) +{ + SetMethodProp32_Replace(oneMethodInfo, NCoderPropID::kNumThreads, numThreads); +} + +#endif // Z7_ST + + +void CMultiMethodProps::InitMulti() { - #ifndef _7ZIP_ST - _numProcessors = _numThreads = NSystem::GetNumberOfProcessors(); - #endif - _level = (UInt32)(Int32)-1; _analysisLevel = -1; - - _autoFilter = true; _crcSize = 4; - _filterMethod.Clear(); + _autoFilter = true; +} + +void CMultiMethodProps::Init() +{ + InitCommon(); + InitMulti(); _methods.Clear(); + _filterMethod.Clear(); } + HRESULT CMultiMethodProps::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value) { UString name = nameSpec; @@ -68,34 +189,32 @@ HRESULT CMultiMethodProps::SetProperty(const wchar_t *nameSpec, const PROPVARIAN { name.Delete(0, 2); UInt32 v = 9; - RINOK(ParsePropToUInt32(name, value, v)); + RINOK(ParsePropToUInt32(name, value, v)) _analysisLevel = (int)v; return S_OK; } - if (name.IsEqualTo("crc")) + if (name.IsPrefixedBy_Ascii_NoCase("crc")) { name.Delete(0, 3); _crcSize = 4; return ParsePropToUInt32(name, value, _crcSize); } + + { + HRESULT hres; + if (SetCommonProperty(name, value, hres)) + return hres; + } UInt32 number; - unsigned index = ParseStringToUInt32(name, number); - UString realName = name.Ptr(index); + const unsigned index = ParseStringToUInt32(name, number); + const UString realName = name.Ptr(index); if (index == 0) { - if (name.IsPrefixedBy_Ascii_NoCase("mt")) - { - #ifndef _7ZIP_ST - RINOK(ParseMtProp(name.Ptr(2), value, _numProcessors, _numThreads)); - #endif - - return S_OK; - } if (name.IsEqualTo("f")) { - HRESULT res = PROPVARIANT_to_bool(value, _autoFilter); + const HRESULT res = PROPVARIANT_to_bool(value, _autoFilter); if (res == S_OK) return res; if (value.vt != VT_BSTR) @@ -105,52 +224,87 @@ HRESULT CMultiMethodProps::SetProperty(const wchar_t *nameSpec, const PROPVARIAN number = 0; } if (number > 64) - return E_FAIL; - for (int j = _methods.Size(); j <= (int)number; j++) - _methods.Add(COneMethodInfo()); + return E_INVALIDARG; + for (unsigned j = _methods.Size(); j <= number; j++) + _methods.AddNew(); return _methods[number].ParseMethodFromPROPVARIANT(realName, value); } + + void CSingleMethodProps::Init() { + InitCommon(); + InitSingle(); Clear(); - _level = (UInt32)(Int32)-1; - - #ifndef _7ZIP_ST - _numProcessors = _numThreads = NWindows::NSystem::GetNumberOfProcessors(); - AddProp_NumThreads(_numThreads); - #endif } + +HRESULT CSingleMethodProps::SetProperty(const wchar_t *name2, const PROPVARIANT &value) +{ + // processed = false; + UString name = name2; + name.MakeLower_Ascii(); + if (name.IsEmpty()) + return E_INVALIDARG; + if (name.IsPrefixedBy_Ascii_NoCase("x")) + { + UInt32 a = 9; + RINOK(ParsePropToUInt32(name.Ptr(1), value, a)) + _level = a; + AddProp_Level(a); + // processed = true; + return S_OK; + } + { + HRESULT hres; + if (SetCommonProperty(name, value, hres)) + { + // processed = true; + return S_OK; + } + } + RINOK(ParseMethodFromPROPVARIANT(name, value)) + return S_OK; +} + + HRESULT CSingleMethodProps::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps) { Init(); + for (UInt32 i = 0; i < numProps; i++) { - UString name = names[i]; - name.MakeLower_Ascii(); - if (name.IsEmpty()) - return E_INVALIDARG; - const PROPVARIANT &value = values[i]; - if (name[0] == L'x') - { - UInt32 a = 9; - RINOK(ParsePropToUInt32(name.Ptr(1), value, a)); - _level = a; - AddProp_Level(a); - } - else if (name.IsPrefixedBy_Ascii_NoCase("mt")) - { - #ifndef _7ZIP_ST - RINOK(ParseMtProp(name.Ptr(2), value, _numProcessors, _numThreads)); - AddProp_NumThreads(_numThreads); - #endif - } - else - { - RINOK(ParseMethodFromPROPVARIANT(names[i], value)); - } + RINOK(SetProperty(names[i], values[i])) + } + + return S_OK; +} + +#endif + + +static HRESULT PROPVARIANT_to_BoolPair(const PROPVARIANT &prop, CBoolPair &dest) +{ + RINOK(PROPVARIANT_to_bool(prop, dest.Val)) + dest.Def = true; + return S_OK; +} + +HRESULT CHandlerTimeOptions::Parse(const UString &name, const PROPVARIANT &prop, bool &processed) +{ + processed = true; + if (name.IsEqualTo_Ascii_NoCase("tm")) { return PROPVARIANT_to_BoolPair(prop, Write_MTime); } + if (name.IsEqualTo_Ascii_NoCase("ta")) { return PROPVARIANT_to_BoolPair(prop, Write_ATime); } + if (name.IsEqualTo_Ascii_NoCase("tc")) { return PROPVARIANT_to_BoolPair(prop, Write_CTime); } + if (name.IsPrefixedBy_Ascii_NoCase("tp")) + { + UInt32 v = 0; + RINOK(ParsePropToUInt32(name.Ptr(2), prop, v)) + Prec = v; + return S_OK; } + processed = false; return S_OK; } diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/HandlerOut.h b/3rdparty/lzma/CPP/7zip/Archive/Common/HandlerOut.h index 5a18d9802b3..cfba46e245b 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/Common/HandlerOut.h +++ b/3rdparty/lzma/CPP/7zip/Archive/Common/HandlerOut.h @@ -1,32 +1,90 @@ // HandlerOut.h -#ifndef __HANDLER_OUT_H -#define __HANDLER_OUT_H +#ifndef ZIP7_INC_HANDLER_OUT_H +#define ZIP7_INC_HANDLER_OUT_H + +#include "../../../Windows/System.h" #include "../../Common/MethodProps.h" namespace NArchive { -class CMultiMethodProps +bool ParseSizeString(const wchar_t *name, const PROPVARIANT &prop, UInt64 percentsBase, UInt64 &res); + +class CCommonMethodProps { - UInt32 _level; - int _analysisLevel; +protected: + void InitCommon() + { + // _Write_MTime = true; + #ifndef Z7_ST + _numProcessors = _numThreads = NWindows::NSystem::GetNumberOfProcessors(); + _numThreads_WasForced = false; + #endif + + UInt64 memAvail = (UInt64)(sizeof(size_t)) << 28; + _memAvail = memAvail; + _memUsage_Compress = memAvail; + _memUsage_Decompress = memAvail; + _memUsage_WasSet = NWindows::NSystem::GetRamSize(memAvail); + if (_memUsage_WasSet) + { + _memAvail = memAvail; + unsigned bits = sizeof(size_t) * 8; + if (bits == 32) + { + const UInt32 limit2 = (UInt32)7 << 28; + if (memAvail > limit2) + memAvail = limit2; + } + // 80% - is auto usage limit in handlers + // _memUsage_Compress = memAvail * 4 / 5; + // _memUsage_Compress = Calc_From_Val_Percents(memAvail, 80); + _memUsage_Compress = Calc_From_Val_Percents_Less100(memAvail, 80); + _memUsage_Decompress = memAvail / 32 * 17; + } + } + public: - #ifndef _7ZIP_ST + #ifndef Z7_ST UInt32 _numThreads; UInt32 _numProcessors; + bool _numThreads_WasForced; #endif + bool _memUsage_WasSet; + UInt64 _memUsage_Compress; + UInt64 _memUsage_Decompress; + UInt64 _memAvail; + + bool SetCommonProperty(const UString &name, const PROPVARIANT &value, HRESULT &hres); + + CCommonMethodProps() { InitCommon(); } +}; + + +#ifndef Z7_EXTRACT_ONLY + +class CMultiMethodProps: public CCommonMethodProps +{ + UInt32 _level; + int _analysisLevel; + + void InitMulti(); +public: UInt32 _crcSize; CObjectVector<COneMethodInfo> _methods; COneMethodInfo _filterMethod; bool _autoFilter; - void SetGlobalLevelAndThreads(COneMethodInfo &oneMethodInfo - #ifndef _7ZIP_ST - , UInt32 numThreads - #endif - ); + + void SetGlobalLevelTo(COneMethodInfo &oneMethodInfo) const; + + #ifndef Z7_ST + static void SetMethodThreadsTo_IfNotFinded(CMethodProps &props, UInt32 numThreads); + static void SetMethodThreadsTo_Replace(CMethodProps &props, UInt32 numThreads); + #endif + unsigned GetNumEmptyMethods() const { @@ -41,27 +99,56 @@ public: int GetAnalysisLevel() const { return _analysisLevel; } void Init(); + CMultiMethodProps() { InitMulti(); } - CMultiMethodProps() { Init(); } HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value); }; -class CSingleMethodProps: public COneMethodInfo + +class CSingleMethodProps: public COneMethodInfo, public CCommonMethodProps { UInt32 _level; - -public: - #ifndef _7ZIP_ST - UInt32 _numThreads; - UInt32 _numProcessors; - #endif + void InitSingle() + { + _level = (UInt32)(Int32)-1; + } + +public: void Init(); - CSingleMethodProps() { Init(); } + CSingleMethodProps() { InitSingle(); } + int GetLevel() const { return _level == (UInt32)(Int32)-1 ? 5 : (int)_level; } + HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &values); HRESULT SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps); }; +#endif + +struct CHandlerTimeOptions +{ + CBoolPair Write_MTime; + CBoolPair Write_ATime; + CBoolPair Write_CTime; + UInt32 Prec; + + void Init() + { + Write_MTime.Init(); + Write_MTime.Val = true; + Write_ATime.Init(); + Write_CTime.Init(); + Prec = (UInt32)(Int32)-1; + } + + CHandlerTimeOptions() + { + Init(); + } + + HRESULT Parse(const UString &name, const PROPVARIANT &prop, bool &processed); +}; + } #endif diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/InStreamWithCRC.cpp b/3rdparty/lzma/CPP/7zip/Archive/Common/InStreamWithCRC.cpp index a2d68832838..735d5d1eb0e 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/Common/InStreamWithCRC.cpp +++ b/3rdparty/lzma/CPP/7zip/Archive/Common/InStreamWithCRC.cpp @@ -4,22 +4,33 @@ #include "InStreamWithCRC.h" -STDMETHODIMP CSequentialInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CSequentialInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize)) { UInt32 realProcessed = 0; HRESULT result = S_OK; - if (_stream) - result = _stream->Read(data, size, &realProcessed); - _size += realProcessed; - if (size != 0 && realProcessed == 0) - _wasFinished = true; - _crc = CrcUpdate(_crc, data, realProcessed); + if (size != 0) + { + if (_stream) + result = _stream->Read(data, size, &realProcessed); + _size += realProcessed; + if (realProcessed == 0) + _wasFinished = true; + else + _crc = CrcUpdate(_crc, data, realProcessed); + } if (processedSize) *processedSize = realProcessed; return result; } -STDMETHODIMP CInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CSequentialInStreamWithCRC::GetSize(UInt64 *size)) +{ + *size = _fullSize; + return S_OK; +} + + +Z7_COM7F_IMF(CInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize)) { UInt32 realProcessed = 0; HRESULT result = S_OK; @@ -36,7 +47,7 @@ STDMETHODIMP CInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSi return result; } -STDMETHODIMP CInStreamWithCRC::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(CInStreamWithCRC::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { if (seekOrigin != STREAM_SEEK_SET || offset != 0) return E_FAIL; diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/InStreamWithCRC.h b/3rdparty/lzma/CPP/7zip/Archive/Common/InStreamWithCRC.h index 31b761e4566..2a91d76742a 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/Common/InStreamWithCRC.h +++ b/3rdparty/lzma/CPP/7zip/Archive/Common/InStreamWithCRC.h @@ -1,7 +1,7 @@ // InStreamWithCRC.h -#ifndef __IN_STREAM_WITH_CRC_H -#define __IN_STREAM_WITH_CRC_H +#ifndef ZIP7_INC_IN_STREAM_WITH_CRC_H +#define ZIP7_INC_IN_STREAM_WITH_CRC_H #include "../../../../C/7zCrc.h" @@ -9,26 +9,29 @@ #include "../../IStream.h" -class CSequentialInStreamWithCRC: - public ISequentialInStream, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); -private: +Z7_CLASS_IMP_NOQIB_2( + CSequentialInStreamWithCRC + , ISequentialInStream + , IStreamGetSize +) CMyComPtr<ISequentialInStream> _stream; UInt64 _size; UInt32 _crc; bool _wasFinished; + UInt64 _fullSize; public: - void SetStream(ISequentialInStream *stream) { _stream = stream; } + + CSequentialInStreamWithCRC(): + _fullSize((UInt64)(Int64)-1) + {} + + void SetStream(ISequentialInStream *stream) { _stream = stream; } + void SetFullSize(UInt64 fullSize) { _fullSize = fullSize; } void Init() { _size = 0; - _wasFinished = false; _crc = CRC_INIT_VAL; + _wasFinished = false; } void ReleaseStream() { _stream.Release(); } UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); } @@ -36,22 +39,19 @@ public: bool WasFinished() const { return _wasFinished; } }; -class CInStreamWithCRC: - public IInStream, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP1(IInStream) - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); -private: +Z7_CLASS_IMP_COM_1( + CInStreamWithCRC, + IInStream +) + Z7_IFACE_COM7_IMP(ISequentialInStream) + CMyComPtr<IInStream> _stream; UInt64 _size; UInt32 _crc; // bool _wasFinished; public: - void SetStream(IInStream *stream) { _stream = stream; } + void SetStream(IInStream *stream) { _stream = stream; } void Init() { _size = 0; diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/ItemNameUtils.cpp b/3rdparty/lzma/CPP/7zip/Archive/Common/ItemNameUtils.cpp index 7cd3037be50..8caf1d141b1 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/Common/ItemNameUtils.cpp +++ b/3rdparty/lzma/CPP/7zip/Archive/Common/ItemNameUtils.cpp @@ -7,58 +7,101 @@ namespace NArchive { namespace NItemName { -static const wchar_t kOSDirDelimiter = WCHAR_PATH_SEPARATOR; -static const wchar_t kDirDelimiter = L'/'; +static const wchar_t kOsPathSepar = WCHAR_PATH_SEPARATOR; -void ReplaceToOsPathSeparator(wchar_t *s) -{ - #ifdef _WIN32 - for (;;) +#if WCHAR_PATH_SEPARATOR != L'/' +static const wchar_t kUnixPathSepar = L'/'; +#endif + +void ReplaceSlashes_OsToUnix +#if WCHAR_PATH_SEPARATOR != L'/' + (UString &name) { - wchar_t c = *s; - if (c == 0) - break; - if (c == kDirDelimiter) - *s = kOSDirDelimiter; - s++; + name.Replace(kOsPathSepar, kUnixPathSepar); } - #endif -} +#else + (UString &) {} +#endif -UString MakeLegalName(const UString &name) -{ - UString zipName = name; - zipName.Replace(kOSDirDelimiter, kDirDelimiter); - return zipName; -} -UString GetOSName(const UString &name) +UString GetOsPath(const UString &name) { - UString newName = name; - newName.Replace(kDirDelimiter, kOSDirDelimiter); - return newName; + #if WCHAR_PATH_SEPARATOR != L'/' + UString newName = name; + newName.Replace(kUnixPathSepar, kOsPathSepar); + return newName; + #else + return name; + #endif } -UString GetOSName2(const UString &name) + +UString GetOsPath_Remove_TailSlash(const UString &name) { if (name.IsEmpty()) return UString(); - UString newName = GetOSName(name); - if (newName.Back() == kOSDirDelimiter) + UString newName = GetOsPath(name); + if (newName.Back() == kOsPathSepar) newName.DeleteBack(); return newName; } -void ConvertToOSName2(UString &name) + +void ReplaceToOsSlashes_Remove_TailSlash(UString &name, bool + #if WCHAR_PATH_SEPARATOR != L'/' + useBackslashReplacement + #endif + ) { - if (!name.IsEmpty()) + if (name.IsEmpty()) + return; + + #if WCHAR_PATH_SEPARATOR != L'/' { - name.Replace(kDirDelimiter, kOSDirDelimiter); - if (name.Back() == kOSDirDelimiter) - name.DeleteBack(); + // name.Replace(kUnixPathSepar, kOsPathSepar); + const unsigned len = name.Len(); + for (unsigned i = 0; i < len; i++) + { + wchar_t c = name[i]; + if (c == L'/') + c = WCHAR_PATH_SEPARATOR; + else if (useBackslashReplacement && c == L'\\') + c = WCHAR_IN_FILE_NAME_BACKSLASH_REPLACEMENT; // WSL scheme + else + continue; + name.ReplaceOneCharAtPos(i, c); + } + } + #endif + + if (name.Back() == kOsPathSepar) + name.DeleteBack(); +} + + +void NormalizeSlashes_in_FileName_for_OsPath(wchar_t *name, unsigned len) +{ + for (unsigned i = 0; i < len; i++) + { + wchar_t c = name[i]; + if (c == L'/') + c = L'_'; + #if WCHAR_PATH_SEPARATOR != L'/' + else if (c == L'\\') + c = WCHAR_IN_FILE_NAME_BACKSLASH_REPLACEMENT; // WSL scheme + #endif + else + continue; + name[i] = c; } } +void NormalizeSlashes_in_FileName_for_OsPath(UString &name) +{ + NormalizeSlashes_in_FileName_for_OsPath(name.GetBuf(), name.Len()); +} + + bool HasTailSlash(const AString &name, UINT #if defined(_WIN32) && !defined(UNDER_CE) codePage @@ -67,20 +110,24 @@ bool HasTailSlash(const AString &name, UINT { if (name.IsEmpty()) return false; - LPCSTR prev = - #if defined(_WIN32) && !defined(UNDER_CE) - CharPrevExA((WORD)codePage, name, &name[name.Len()], 0); - #else - (LPCSTR)(name) + (name.Len() - 1); - #endif - return (*prev == '/'); + char c; + #if defined(_WIN32) && !defined(UNDER_CE) + if (codePage != CP_UTF8) + c = *CharPrevExA((WORD)codePage, name, name.Ptr(name.Len()), 0); + else + #endif + { + c = name.Back(); + } + return (c == '/'); } + #ifndef _WIN32 -UString WinNameToOSName(const UString &name) +UString WinPathToOsPath(const UString &name) { UString newName = name; - newName.Replace(L'\\', kOSDirDelimiter); + newName.Replace(L'\\', WCHAR_PATH_SEPARATOR); return newName; } #endif diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/ItemNameUtils.h b/3rdparty/lzma/CPP/7zip/Archive/Common/ItemNameUtils.h index d0dc76a4109..8ab9b610a0f 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/Common/ItemNameUtils.h +++ b/3rdparty/lzma/CPP/7zip/Archive/Common/ItemNameUtils.h @@ -1,26 +1,29 @@ // Archive/Common/ItemNameUtils.h -#ifndef __ARCHIVE_ITEM_NAME_UTILS_H -#define __ARCHIVE_ITEM_NAME_UTILS_H +#ifndef ZIP7_INC_ARCHIVE_ITEM_NAME_UTILS_H +#define ZIP7_INC_ARCHIVE_ITEM_NAME_UTILS_H #include "../../../Common/MyString.h" namespace NArchive { namespace NItemName { - void ReplaceToOsPathSeparator(wchar_t *s); - - UString MakeLegalName(const UString &name); - UString GetOSName(const UString &name); - UString GetOSName2(const UString &name); - void ConvertToOSName2(UString &name); - bool HasTailSlash(const AString &name, UINT codePage); - - #ifdef _WIN32 - inline UString WinNameToOSName(const UString &name) { return name; } - #else - UString WinNameToOSName(const UString &name); - #endif +void ReplaceSlashes_OsToUnix(UString &name); + +UString GetOsPath(const UString &name); +UString GetOsPath_Remove_TailSlash(const UString &name); + +void ReplaceToOsSlashes_Remove_TailSlash(UString &name, bool useBackslashReplacement = false); +void NormalizeSlashes_in_FileName_for_OsPath(wchar_t *s, unsigned len); +void NormalizeSlashes_in_FileName_for_OsPath(UString &name); + +bool HasTailSlash(const AString &name, UINT codePage); + +#ifdef _WIN32 + inline UString WinPathToOsPath(const UString &name) { return name; } +#else + UString WinPathToOsPath(const UString &name); +#endif }} diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/MultiStream.cpp b/3rdparty/lzma/CPP/7zip/Archive/Common/MultiStream.cpp index 1de74afe43e..5d357af7113 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/Common/MultiStream.cpp +++ b/3rdparty/lzma/CPP/7zip/Archive/Common/MultiStream.cpp @@ -4,7 +4,7 @@ #include "MultiStream.h" -STDMETHODIMP CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -23,10 +23,7 @@ STDMETHODIMP CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize) else if (_pos >= m.GlobalOffset + m.Size) left = mid + 1; else - { - _streamIndex = mid; break; - } mid = (left + right) / 2; } _streamIndex = mid; @@ -36,12 +33,14 @@ STDMETHODIMP CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize) UInt64 localPos = _pos - s.GlobalOffset; if (localPos != s.LocalPos) { - RINOK(s.Stream->Seek(localPos, STREAM_SEEK_SET, &s.LocalPos)); + RINOK(s.Stream->Seek((Int64)localPos, STREAM_SEEK_SET, &s.LocalPos)) } - UInt64 rem = s.Size - localPos; - if (size > rem) - size = (UInt32)rem; - HRESULT result = s.Stream->Read(data, size, &size); + { + const UInt64 rem = s.Size - localPos; + if (size > rem) + size = (UInt32)rem; + } + const HRESULT result = s.Stream->Read(data, size, &size); _pos += size; s.LocalPos += size; if (processedSize) @@ -49,7 +48,7 @@ STDMETHODIMP CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize) return result; } -STDMETHODIMP CMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(CMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { switch (seekOrigin) { @@ -60,9 +59,9 @@ STDMETHODIMP CMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosi } if (offset < 0) return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - _pos = offset; + _pos = (UInt64)offset; if (newPosition) - *newPosition = offset; + *newPosition = (UInt64)offset; return S_OK; } @@ -72,6 +71,9 @@ class COutVolumeStream: public ISequentialOutStream, public CMyUnknownImp { + Z7_COM_UNKNOWN_IMP_0 + Z7_IFACE_COM7_IMP(ISequentialOutStream) + unsigned _volIndex; UInt64 _volSize; UInt64 _curPos; @@ -80,8 +82,6 @@ class COutVolumeStream: CCRC _crc; public: - MY_UNKNOWN_IMP - CFileItem _file; CUpdateOptions _options; CMyComPtr<IArchiveUpdateCallback2> VolumeCallback; @@ -98,7 +98,6 @@ public: } HRESULT Flush(); - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); }; HRESULT COutVolumeStream::Flush() @@ -107,7 +106,7 @@ HRESULT COutVolumeStream::Flush() { _file.UnPackSize = _curPos; _file.FileCRC = _crc.GetDigest(); - RINOK(WriteVolumeHeader(_archive, _file, _options)); + RINOK(WriteVolumeHeader(_archive, _file, _options)) _archive.Close(); _volumeStream.Release(); _file.StartPos += _file.UnPackSize; @@ -117,7 +116,10 @@ HRESULT COutVolumeStream::Flush() */ /* -STDMETHODIMP COutMultiStream::Write(const void *data, UInt32 size, UInt32 *processedSize) + +#include "../../../Common/Defs.h" + +Z7_COM7F_IMF(COutMultiStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -126,8 +128,8 @@ STDMETHODIMP COutMultiStream::Write(const void *data, UInt32 size, UInt32 *proce if (_streamIndex >= Streams.Size()) { CSubStreamInfo subStream; - RINOK(VolumeCallback->GetVolumeSize(Streams.Size(), &subStream.Size)); - RINOK(VolumeCallback->GetVolumeStream(Streams.Size(), &subStream.Stream)); + RINOK(VolumeCallback->GetVolumeSize(Streams.Size(), &subStream.Size)) + RINOK(VolumeCallback->GetVolumeStream(Streams.Size(), &subStream.Stream)) subStream.Pos = 0; Streams.Add(subStream); continue; @@ -142,15 +144,15 @@ STDMETHODIMP COutMultiStream::Write(const void *data, UInt32 size, UInt32 *proce if (_offsetPos != subStream.Pos) { CMyComPtr<IOutStream> outStream; - RINOK(subStream.Stream.QueryInterface(IID_IOutStream, &outStream)); - RINOK(outStream->Seek(_offsetPos, STREAM_SEEK_SET, NULL)); + RINOK(subStream.Stream.QueryInterface(IID_IOutStream, &outStream)) + RINOK(outStream->Seek((Int64)_offsetPos, STREAM_SEEK_SET, NULL)) subStream.Pos = _offsetPos; } - UInt32 curSize = (UInt32)MyMin((UInt64)size, subStream.Size - subStream.Pos); + const UInt32 curSize = (UInt32)MyMin((UInt64)size, subStream.Size - subStream.Pos); UInt32 realProcessed; - RINOK(subStream.Stream->Write(data, curSize, &realProcessed)); - data = (void *)((Byte *)data + realProcessed); + RINOK(subStream.Stream->Write(data, curSize, &realProcessed)) + data = (const void *)((const Byte *)data + realProcessed); size -= realProcessed; subStream.Pos += realProcessed; _offsetPos += realProcessed; @@ -170,7 +172,7 @@ STDMETHODIMP COutMultiStream::Write(const void *data, UInt32 size, UInt32 *proce return S_OK; } -STDMETHODIMP COutMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(COutMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { switch (seekOrigin) { @@ -181,11 +183,11 @@ STDMETHODIMP COutMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newP } if (offset < 0) return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - _absPos = offset; + _absPos = (UInt64)offset; _offsetPos = _absPos; _streamIndex = 0; if (newPosition) - *newPosition = offset; + *newPosition = (UInt64)offset; return S_OK; } */ diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/MultiStream.h b/3rdparty/lzma/CPP/7zip/Archive/Common/MultiStream.h index c10cd455729..e3096f58d93 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/Common/MultiStream.h +++ b/3rdparty/lzma/CPP/7zip/Archive/Common/MultiStream.h @@ -1,20 +1,23 @@ // MultiStream.h -#ifndef __MULTI_STREAM_H -#define __MULTI_STREAM_H +#ifndef ZIP7_INC_MULTI_STREAM_H +#define ZIP7_INC_MULTI_STREAM_H #include "../../../Common/MyCom.h" #include "../../../Common/MyVector.h" #include "../../IStream.h" +#include "../../Archive/IArchive.h" -class CMultiStream: - public IInStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_1( + CMultiStream + , IInStream +) + Z7_IFACE_COM7_IMP(ISequentialInStream) + + unsigned _streamIndex; UInt64 _pos; UInt64 _totalLength; - unsigned _streamIndex; public: @@ -24,12 +27,12 @@ public: UInt64 Size; UInt64 GlobalOffset; UInt64 LocalPos; - CSubStreamInfo(): Size(0), GlobalOffset(0), LocalPos(0) {} }; - + + CMyComPtr<IArchiveUpdateCallbackFile> updateCallbackFile; CObjectVector<CSubStreamInfo> Streams; - + HRESULT Init() { UInt64 total = 0; @@ -37,26 +40,27 @@ public: { CSubStreamInfo &s = Streams[i]; s.GlobalOffset = total; - total += Streams[i].Size; - RINOK(s.Stream->Seek(0, STREAM_SEEK_CUR, &s.LocalPos)); + total += s.Size; + s.LocalPos = 0; + { + // it was already set to start + // RINOK(InStream_GetPos(s.Stream, s.LocalPos)); + } } _totalLength = total; _pos = 0; _streamIndex = 0; return S_OK; } - - MY_UNKNOWN_IMP1(IInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); }; /* -class COutMultiStream: - public IOutStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_1( + COutMultiStream, + IOutStream +) + Z7_IFACE_COM7_IMP(ISequentialOutStream) + unsigned _streamIndex; // required stream UInt64 _offsetPos; // offset from start of _streamIndex index UInt64 _absPos; @@ -78,11 +82,6 @@ public: _absPos = 0; _length = 0; } - - MY_UNKNOWN_IMP1(IOutStream) - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); }; */ diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp b/3rdparty/lzma/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp index f955c22547b..7dcd44ac13c 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp +++ b/3rdparty/lzma/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp @@ -4,7 +4,7 @@ #include "OutStreamWithCRC.h" -STDMETHODIMP COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *processedSize)) { HRESULT result = S_OK; if (_stream) @@ -12,7 +12,7 @@ STDMETHODIMP COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *pro if (_calculate) _crc = CrcUpdate(_crc, data, size); _size += size; - if (processedSize != NULL) + if (processedSize) *processedSize = size; return result; } diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/OutStreamWithCRC.h b/3rdparty/lzma/CPP/7zip/Archive/Common/OutStreamWithCRC.h index 09b899bbd74..845146a1b9d 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/Common/OutStreamWithCRC.h +++ b/3rdparty/lzma/CPP/7zip/Archive/Common/OutStreamWithCRC.h @@ -1,7 +1,7 @@ // OutStreamWithCRC.h -#ifndef __OUT_STREAM_WITH_CRC_H -#define __OUT_STREAM_WITH_CRC_H +#ifndef ZIP7_INC_OUT_STREAM_WITH_CRC_H +#define ZIP7_INC_OUT_STREAM_WITH_CRC_H #include "../../../../C/7zCrc.h" @@ -9,17 +9,15 @@ #include "../../IStream.h" -class COutStreamWithCRC: - public ISequentialOutStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_NOQIB_1( + COutStreamWithCRC + , ISequentialOutStream +) CMyComPtr<ISequentialOutStream> _stream; UInt64 _size; UInt32 _crc; bool _calculate; public: - MY_UNKNOWN_IMP - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); void SetStream(ISequentialOutStream *stream) { _stream = stream; } void ReleaseStream() { _stream.Release(); } void Init(bool calculate = true) diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/ParseProperties.h b/3rdparty/lzma/CPP/7zip/Archive/Common/ParseProperties.h index 1038a8c020c..4ec2e48ed9d 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/Common/ParseProperties.h +++ b/3rdparty/lzma/CPP/7zip/Archive/Common/ParseProperties.h @@ -1,6 +1,6 @@ // ParseProperties.h -#ifndef __PARSE_PROPERTIES_H -#define __PARSE_PROPERTIES_H +#ifndef ZIP7_INC_PARSE_PROPERTIES_H +#define ZIP7_INC_PARSE_PROPERTIES_H #endif diff --git a/3rdparty/lzma/CPP/7zip/Archive/Common/StdAfx.h b/3rdparty/lzma/CPP/7zip/Archive/Common/StdAfx.h index 2854ff3e935..035267ccd02 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/Common/StdAfx.h +++ b/3rdparty/lzma/CPP/7zip/Archive/Common/StdAfx.h @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../../Common/Common.h" #endif diff --git a/3rdparty/lzma/CPP/7zip/Archive/DllExports2.cpp b/3rdparty/lzma/CPP/7zip/Archive/DllExports2.cpp index 10889e75521..ae8d8acc19c 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/DllExports2.cpp +++ b/3rdparty/lzma/CPP/7zip/Archive/DllExports2.cpp @@ -3,10 +3,9 @@ #include "StdAfx.h" #include "../../Common/MyWindows.h" - #include "../../Common/MyInitGuid.h" -#if defined(_7ZIP_LARGE_PAGES) +#if defined(Z7_LARGE_PAGES) #include "../../../C/Alloc.h" #endif @@ -22,11 +21,25 @@ #include "IArchive.h" -HINSTANCE g_hInstance; +#ifdef _WIN32 + +#if defined(_UNICODE) && !defined(_WIN64) && !defined(UNDER_CE) #define NT_CHECK_FAIL_ACTION return FALSE; +#endif + +static +HINSTANCE g_hInstance; + +extern "C" +BOOL WINAPI DllMain( + #ifdef UNDER_CE + HANDLE + #else + HINSTANCE + #endif + hInstance, DWORD dwReason, LPVOID /*lpReserved*/); -#ifdef _WIN32 extern "C" BOOL WINAPI DllMain( #ifdef UNDER_CE @@ -40,7 +53,7 @@ BOOL WINAPI DllMain( { // OutputDebugStringA("7z.dll DLL_PROCESS_ATTACH"); g_hInstance = (HINSTANCE)hInstance; - NT_CHECK; + NT_CHECK } /* if (dwReason == DLL_PROCESS_DETACH) @@ -50,9 +63,24 @@ BOOL WINAPI DllMain( */ return TRUE; } -#endif -DEFINE_GUID(CLSID_CArchiveHandler, +#else // _WIN32 + +#include "../../Common/StringConvert.h" +// #include <stdio.h> + +// STDAPI LibStartup(); +static __attribute__((constructor)) void Init_ForceToUTF8(); +static __attribute__((constructor)) void Init_ForceToUTF8() +{ + g_ForceToUTF8 = IsNativeUTF8(); + // printf("\nDLLExports2.cpp::Init_ForceToUTF8 =%d\n", g_ForceToUTF8 ? 1 : 0); +} + +#endif // _WIN32 + + +Z7_DEFINE_GUID(CLSID_CArchiveHandler, k_7zip_GUID_Data1, k_7zip_GUID_Data2, k_7zip_GUID_Data3_Common, @@ -62,10 +90,11 @@ STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject); STDAPI CreateHasher(const GUID *clsid, IHasher **hasher); STDAPI CreateArchiver(const GUID *clsid, const GUID *iid, void **outObject); +STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject); STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject) { // COM_TRY_BEGIN - *outObject = 0; + *outObject = NULL; if (*iid == IID_ICompressCoder || *iid == IID_ICompressCoder2 || *iid == IID_ICompressFilter) @@ -76,26 +105,49 @@ STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject) // COM_TRY_END } +STDAPI SetLargePageMode(); STDAPI SetLargePageMode() { - #if defined(_7ZIP_LARGE_PAGES) + #if defined(Z7_LARGE_PAGES) + #ifdef _WIN32 SetLargePageSize(); #endif + #endif return S_OK; } extern bool g_CaseSensitive; +STDAPI SetCaseSensitive(Int32 caseSensitive); STDAPI SetCaseSensitive(Int32 caseSensitive) { g_CaseSensitive = (caseSensitive != 0); return S_OK; } -#ifdef EXTERNAL_CODECS +/* +UInt32 g_ClientVersion; +STDAPI SetClientVersion(UInt32 version); +STDAPI SetClientVersion(UInt32 version) +{ + g_ClientVersion = version; + return S_OK; +} +*/ + +/* +STDAPI SetProperty(Int32 id, const PROPVARIANT *value); +STDAPI SetProperty(Int32 id, const PROPVARIANT *value) +{ + return S_OK; +} +*/ + +#ifdef Z7_EXTERNAL_CODECS CExternalCodecs g_ExternalCodecs; +STDAPI SetCodecs(ICompressCodecsInfo *compressCodecsInfo); STDAPI SetCodecs(ICompressCodecsInfo *compressCodecsInfo) { COM_TRY_BEGIN @@ -114,6 +166,7 @@ STDAPI SetCodecs(ICompressCodecsInfo *compressCodecsInfo) #else +STDAPI SetCodecs(ICompressCodecsInfo *); STDAPI SetCodecs(ICompressCodecsInfo *) { return S_OK; diff --git a/3rdparty/lzma/CPP/7zip/Archive/IArchive.h b/3rdparty/lzma/CPP/7zip/Archive/IArchive.h index 0028d76246b..3e68ac30099 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/IArchive.h +++ b/3rdparty/lzma/CPP/7zip/Archive/IArchive.h @@ -1,22 +1,55 @@ // IArchive.h -#ifndef __IARCHIVE_H -#define __IARCHIVE_H +#ifndef ZIP7_INC_IARCHIVE_H +#define ZIP7_INC_IARCHIVE_H #include "../IProgress.h" #include "../IStream.h" #include "../PropID.h" -#define ARCHIVE_INTERFACE_SUB(i, base, x) DECL_INTERFACE_SUB(i, base, 6, x) -#define ARCHIVE_INTERFACE(i, x) ARCHIVE_INTERFACE_SUB(i, IUnknown, x) +Z7_PURE_INTERFACES_BEGIN + + +#define Z7_IFACE_CONSTR_ARCHIVE_SUB(i, base, n) \ + Z7_DECL_IFACE_7ZIP_SUB(i, base, 6, n) \ + { Z7_IFACE_COM7_PURE(i) }; + +#define Z7_IFACE_CONSTR_ARCHIVE(i, n) \ + Z7_IFACE_CONSTR_ARCHIVE_SUB(i, IUnknown, n) + +/* +How the function in 7-Zip returns object for output parameter via pointer + +1) The caller sets the value of variable before function call: + PROPVARIANT : vt = VT_EMPTY + BSTR : NULL + IUnknown* and derived interfaces : NULL + another scalar types : any non-initialized value is allowed + +2) The callee in current 7-Zip code now can free input object for output parameter: + PROPVARIANT : the callee calls VariantClear(propvaiant_ptr) for input + value stored in variable + another types : the callee ignores stored value. + +3) The callee writes new value to variable for output parameter and + returns execution to caller. + +4) The caller must free or release object returned by the callee: + PROPVARIANT : VariantClear(&propvaiant) + BSTR : SysFreeString(bstr) + IUnknown* and derived interfaces : if (ptr) ptr->Relase() +*/ + namespace NFileTimeType { enum EEnum { - kWindows, + kNotDefined = -1, + kWindows = 0, kUnix, - kDOS + kDOS, + k1ns }; } @@ -34,8 +67,33 @@ namespace NArcInfoFlags const UInt32 kPreArc = 1 << 9; // such archive can be stored before real archive (like SFX stub) const UInt32 kSymLinks = 1 << 10; // the handler supports symbolic links const UInt32 kHardLinks = 1 << 11; // the handler supports hard links + const UInt32 kByExtOnlyOpen = 1 << 12; // call handler only if file extension matches + const UInt32 kHashHandler = 1 << 13; // the handler contains the hashes (checksums) + const UInt32 kCTime = 1 << 14; + const UInt32 kCTime_Default = 1 << 15; + const UInt32 kATime = 1 << 16; + const UInt32 kATime_Default = 1 << 17; + const UInt32 kMTime = 1 << 18; + const UInt32 kMTime_Default = 1 << 19; + // const UInt32 kTTime_Reserved = 1 << 20; + // const UInt32 kTTime_Reserved_Default = 1 << 21; } +namespace NArcInfoTimeFlags +{ + const unsigned kTime_Prec_Mask_bit_index = 0; + const unsigned kTime_Prec_Mask_num_bits = 26; + + const unsigned kTime_Prec_Default_bit_index = 27; + const unsigned kTime_Prec_Default_num_bits = 5; +} + +#define TIME_PREC_TO_ARC_FLAGS_MASK(v) \ + ((UInt32)1 << (NArcInfoTimeFlags::kTime_Prec_Mask_bit_index + (v))) + +#define TIME_PREC_TO_ARC_FLAGS_TIME_DEFAULT(v) \ + ((UInt32)(v) << NArcInfoTimeFlags::kTime_Prec_Default_bit_index) + namespace NArchive { namespace NHandlerPropID @@ -53,8 +111,8 @@ namespace NArchive kSignatureOffset, // VT_UI4 kAltStreams, // VT_BOOL kNtSecure, // VT_BOOL - kFlags // VT_UI4 - // kVersion // VT_UI4 ((VER_MAJOR << 8) | VER_MINOR) + kFlags, // VT_UI4 + kTimeFlags // VT_UI4 }; } @@ -66,7 +124,8 @@ namespace NArchive { kExtract = 0, kTest, - kSkip + kSkip, + kReadExternal }; } @@ -84,6 +143,7 @@ namespace NArchive kIsNotArc, kHeadersError, kWrongPassword + // , kMemError }; } } @@ -96,6 +156,7 @@ namespace NArchive kInArcIndex, kBlockIndex, kOutArcIndex + // kArcProp }; } @@ -106,20 +167,18 @@ namespace NArchive enum { kOK = 0 - , // kError + // kError = 1, + // kError_FileChanged }; } } } -#define INTERFACE_IArchiveOpenCallback(x) \ - STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes) x; \ - STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes) x; \ +#define Z7_IFACEM_IArchiveOpenCallback(x) \ + x(SetTotal(const UInt64 *files, const UInt64 *bytes)) \ + x(SetCompleted(const UInt64 *files, const UInt64 *bytes)) \ -ARCHIVE_INTERFACE(IArchiveOpenCallback, 0x10) -{ - INTERFACE_IArchiveOpenCallback(PURE); -}; +Z7_IFACE_CONSTR_ARCHIVE(IArchiveOpenCallback, 0x10) /* IArchiveExtractCallback:: @@ -137,13 +196,13 @@ IArchiveExtractCallback::GetStream() Int32 askExtractMode (Extract::NAskMode) if (askMode != NExtract::NAskMode::kExtract) { - then the callee can not real stream: (*inStream == NULL) + then the callee doesn't write data to stream: (*outStream == NULL) } Out: - (*inStream == NULL) - for directories - (*inStream == NULL) - if link (hard link or symbolic link) was created - if (*inStream == NULL && askMode == NExtract::NAskMode::kExtract) + (*outStream == NULL) - for directories + (*outStream == NULL) - if link (hard link or symbolic link) was created + if (*outStream == NULL && askMode == NExtract::NAskMode::kExtract) { then the caller must skip extracting of that file. } @@ -170,57 +229,49 @@ SetOperationResult() Int32 opRes (NExtract::NOperationResult) */ -#define INTERFACE_IArchiveExtractCallback(x) \ - INTERFACE_IProgress(x) \ - STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode) x; \ - STDMETHOD(PrepareOperation)(Int32 askExtractMode) x; \ - STDMETHOD(SetOperationResult)(Int32 opRes) x; \ +// INTERFACE_IProgress(x) -ARCHIVE_INTERFACE_SUB(IArchiveExtractCallback, IProgress, 0x20) -{ - INTERFACE_IArchiveExtractCallback(PURE) -}; +#define Z7_IFACEM_IArchiveExtractCallback(x) \ + x(GetStream(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode)) \ + x(PrepareOperation(Int32 askExtractMode)) \ + x(SetOperationResult(Int32 opRes)) \ + +Z7_IFACE_CONSTR_ARCHIVE_SUB(IArchiveExtractCallback, IProgress, 0x20) /* -IArchiveExtractCallbackMessage can be requested from IArchiveExtractCallback object +v23: +IArchiveExtractCallbackMessage2 can be requested from IArchiveExtractCallback object by Extract() or UpdateItems() functions to report about extracting errors ReportExtractResult() UInt32 indexType (NEventIndexType) UInt32 index Int32 opRes (NExtract::NOperationResult) */ +/* +before v23: +#define Z7_IFACEM_IArchiveExtractCallbackMessage(x) \ + x(ReportExtractResult(UInt32 indexType, UInt32 index, Int32 opRes)) +Z7_IFACE_CONSTR_ARCHIVE_SUB(IArchiveExtractCallbackMessage, IProgress, 0x21) +*/ +#define Z7_IFACEM_IArchiveExtractCallbackMessage2(x) \ + x(ReportExtractResult(UInt32 indexType, UInt32 index, Int32 opRes)) +Z7_IFACE_CONSTR_ARCHIVE(IArchiveExtractCallbackMessage2, 0x22) -#define INTERFACE_IArchiveExtractCallbackMessage(x) \ - STDMETHOD(ReportExtractResult)(UInt32 indexType, UInt32 index, Int32 opRes) x; \ - -ARCHIVE_INTERFACE_SUB(IArchiveExtractCallbackMessage, IProgress, 0x21) -{ - INTERFACE_IArchiveExtractCallbackMessage(PURE) -}; - - -#define INTERFACE_IArchiveOpenVolumeCallback(x) \ - STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value) x; \ - STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream) x; \ - -ARCHIVE_INTERFACE(IArchiveOpenVolumeCallback, 0x30) -{ - INTERFACE_IArchiveOpenVolumeCallback(PURE); -}; - +#define Z7_IFACEM_IArchiveOpenVolumeCallback(x) \ + x(GetProperty(PROPID propID, PROPVARIANT *value)) \ + x(GetStream(const wchar_t *name, IInStream **inStream)) +Z7_IFACE_CONSTR_ARCHIVE(IArchiveOpenVolumeCallback, 0x30) -ARCHIVE_INTERFACE(IInArchiveGetStream, 0x40) -{ - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream) PURE; -}; +#define Z7_IFACEM_IInArchiveGetStream(x) \ + x(GetStream(UInt32 index, ISequentialInStream **stream)) +Z7_IFACE_CONSTR_ARCHIVE(IInArchiveGetStream, 0x40) -ARCHIVE_INTERFACE(IArchiveOpenSetSubArchiveName, 0x50) -{ - STDMETHOD(SetSubArchiveName)(const wchar_t *name) PURE; -}; +#define Z7_IFACEM_IArchiveOpenSetSubArchiveName(x) \ + x(SetSubArchiveName(const wchar_t *name)) +Z7_IFACE_CONSTR_ARCHIVE(IArchiveOpenSetSubArchiveName, 0x50) /* @@ -256,28 +307,25 @@ Notes: Some IInArchive handlers will work incorrectly in that case. */ -#ifdef _MSC_VER - #define MY_NO_THROW_DECL_ONLY throw() +#if defined(_MSC_VER) && !defined(__clang__) + #define MY_NO_THROW_DECL_ONLY Z7_COM7F_E #else #define MY_NO_THROW_DECL_ONLY #endif -#define INTERFACE_IInArchive(x) \ - STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openCallback) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(Close)() MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetNumberOfItems)(UInt32 *numItems) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetNumberOfProperties)(UInt32 *numProps) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProps) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) MY_NO_THROW_DECL_ONLY x; \ - -ARCHIVE_INTERFACE(IInArchive, 0x60) -{ - INTERFACE_IInArchive(PURE) -}; +#define Z7_IFACEM_IInArchive(x) \ + x(Open(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openCallback)) \ + x(Close()) \ + x(GetNumberOfItems(UInt32 *numItems)) \ + x(GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) \ + x(Extract(const UInt32 *indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback)) \ + x(GetArchiveProperty(PROPID propID, PROPVARIANT *value)) \ + x(GetNumberOfProperties(UInt32 *numProps)) \ + x(GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)) \ + x(GetNumberOfArchiveProperties(UInt32 *numProps)) \ + x(GetArchivePropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)) \ + +Z7_IFACE_CONSTR_ARCHIVE(IInArchive, 0x60) namespace NParentType { @@ -286,7 +334,7 @@ namespace NParentType kDir = 0, kAltStream }; -}; +} namespace NPropDataType { @@ -302,41 +350,36 @@ namespace NPropDataType const UInt32 kUtf8z = kMask_Utf8 | kMask_ZeroEnd; const UInt32 kUtf16z = kMask_Utf16 | kMask_ZeroEnd; -}; +} // UTF string (pointer to wchar_t) with zero end and little-endian. #define PROP_DATA_TYPE_wchar_t_PTR_Z_LE ((NPropDataType::kMask_Utf | NPropDataType::kMask_ZeroEnd) + (sizeof(wchar_t) >> 1)) + /* GetRawProp: Result: S_OK - even if property is not set */ -#define INTERFACE_IArchiveGetRawProps(x) \ - STDMETHOD(GetParent)(UInt32 index, UInt32 *parent, UInt32 *parentType) x; \ - STDMETHOD(GetRawProp)(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) x; \ - STDMETHOD(GetNumRawProps)(UInt32 *numProps) x; \ - STDMETHOD(GetRawPropInfo)(UInt32 index, BSTR *name, PROPID *propID) x; +#define Z7_IFACEM_IArchiveGetRawProps(x) \ + x(GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType)) \ + x(GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)) \ + x(GetNumRawProps(UInt32 *numProps)) \ + x(GetRawPropInfo(UInt32 index, BSTR *name, PROPID *propID)) -ARCHIVE_INTERFACE(IArchiveGetRawProps, 0x70) -{ - INTERFACE_IArchiveGetRawProps(PURE) -}; +Z7_IFACE_CONSTR_ARCHIVE(IArchiveGetRawProps, 0x70) -#define INTERFACE_IArchiveGetRootProps(x) \ - STDMETHOD(GetRootProp)(PROPID propID, PROPVARIANT *value) x; \ - STDMETHOD(GetRootRawProp)(PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) x; \ +#define Z7_IFACEM_IArchiveGetRootProps(x) \ + x(GetRootProp(PROPID propID, PROPVARIANT *value)) \ + x(GetRootRawProp(PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)) \ -ARCHIVE_INTERFACE(IArchiveGetRootProps, 0x71) -{ - INTERFACE_IArchiveGetRootProps(PURE) -}; +Z7_IFACE_CONSTR_ARCHIVE(IArchiveGetRootProps, 0x71) -ARCHIVE_INTERFACE(IArchiveOpenSeq, 0x61) -{ - STDMETHOD(OpenSeq)(ISequentialInStream *stream) PURE; -}; +#define Z7_IFACEM_IArchiveOpenSeq(x) \ + x(OpenSeq(ISequentialInStream *stream)) \ + +Z7_IFACE_CONSTR_ARCHIVE(IArchiveOpenSeq, 0x61) /* OpenForSize @@ -362,12 +405,10 @@ Flags: the handler can return S_OK, but it doesn't check even Signature. So next Extract can be called for that sequential stream. */ - /* -ARCHIVE_INTERFACE(IArchiveOpen2, 0x62) -{ - STDMETHOD(ArcOpen2)(ISequentialInStream *stream, UInt32 flags, IArchiveOpenCallback *openCallback) PURE; -}; +#define Z7_IFACEM_IArchiveOpen2(x) \ + x(ArcOpen2(ISequentialInStream *stream, UInt32 flags, IArchiveOpenCallback *openCallback)) +Z7_IFACE_CONSTR_ARCHIVE(IArchiveOpen2, 0x62) */ // ---------- UPDATE ---------- @@ -400,27 +441,21 @@ SetOperationResult() Int32 opRes (NExtract::NOperationResult::kOK) */ -#define INTERFACE_IArchiveUpdateCallback(x) \ - INTERFACE_IProgress(x); \ - STDMETHOD(GetUpdateItemInfo)(UInt32 index, Int32 *newData, Int32 *newProps, UInt32 *indexInArchive) x; \ - STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) x; \ - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream) x; \ - STDMETHOD(SetOperationResult)(Int32 operationResult) x; \ +// INTERFACE_IProgress(x) +#define Z7_IFACEM_IArchiveUpdateCallback(x) \ + x(GetUpdateItemInfo(UInt32 index, Int32 *newData, Int32 *newProps, UInt32 *indexInArchive)) \ + x(GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) \ + x(GetStream(UInt32 index, ISequentialInStream **inStream)) \ + x(SetOperationResult(Int32 operationResult)) \ -ARCHIVE_INTERFACE_SUB(IArchiveUpdateCallback, IProgress, 0x80) -{ - INTERFACE_IArchiveUpdateCallback(PURE); -}; +Z7_IFACE_CONSTR_ARCHIVE_SUB(IArchiveUpdateCallback, IProgress, 0x80) -#define INTERFACE_IArchiveUpdateCallback2(x) \ - INTERFACE_IArchiveUpdateCallback(x) \ - STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size) x; \ - STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream) x; \ +// INTERFACE_IArchiveUpdateCallback(x) +#define Z7_IFACEM_IArchiveUpdateCallback2(x) \ + x(GetVolumeSize(UInt32 index, UInt64 *size)) \ + x(GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream)) \ -ARCHIVE_INTERFACE_SUB(IArchiveUpdateCallback2, IArchiveUpdateCallback, 0x82) -{ - INTERFACE_IArchiveUpdateCallback2(PURE); -}; +Z7_IFACE_CONSTR_ARCHIVE_SUB(IArchiveUpdateCallback2, IArchiveUpdateCallback, 0x82) namespace NUpdateNotifyOp { @@ -433,11 +468,13 @@ namespace NUpdateNotifyOp kRepack, kSkip, kDelete, - kHeader - - // kNumDefined + kHeader, + kHashRead, + kInFileChanged + // , kOpFinished + // , kNumDefined }; -}; +} /* IArchiveUpdateCallbackFile::ReportOperation @@ -446,16 +483,28 @@ IArchiveUpdateCallbackFile::ReportOperation UInt32 notifyOp (NUpdateNotifyOp) */ -#define INTERFACE_IArchiveUpdateCallbackFile(x) \ - STDMETHOD(GetStream2)(UInt32 index, ISequentialInStream **inStream, UInt32 notifyOp) x; \ - STDMETHOD(ReportOperation)(UInt32 indexType, UInt32 index, UInt32 notifyOp) x; \ +#define Z7_IFACEM_IArchiveUpdateCallbackFile(x) \ + x(GetStream2(UInt32 index, ISequentialInStream **inStream, UInt32 notifyOp)) \ + x(ReportOperation(UInt32 indexType, UInt32 index, UInt32 notifyOp)) \ -ARCHIVE_INTERFACE(IArchiveUpdateCallbackFile, 0x83) -{ - INTERFACE_IArchiveUpdateCallbackFile(PURE); -}; +Z7_IFACE_CONSTR_ARCHIVE(IArchiveUpdateCallbackFile, 0x83) +#define Z7_IFACEM_IArchiveGetDiskProperty(x) \ + x(GetDiskProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) \ + +Z7_IFACE_CONSTR_ARCHIVE(IArchiveGetDiskProperty, 0x84) + +/* +#define Z7_IFACEM_IArchiveUpdateCallbackArcProp(x) \ + x(ReportProp(UInt32 indexType, UInt32 index, PROPID propID, const PROPVARIANT *value)) \ + x(ReportRawProp(UInt32 indexType, UInt32 index, PROPID propID, const void *data, UInt32 dataSize, UInt32 propType)) \ + x(ReportFinished(UInt32 indexType, UInt32 index, Int32 opRes)) \ + x(DoNeedArcProp(PROPID propID, Int32 *answer)) \ + +Z7_IFACE_CONSTR_ARCHIVE(IArchiveUpdateCallbackArcProp, 0x85) +*/ + /* UpdateItems() ------------- @@ -478,41 +527,43 @@ UpdateItems() */ -#define INTERFACE_IOutArchive(x) \ - STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback) x; \ - STDMETHOD(GetFileTimeType)(UInt32 *type) x; +#define Z7_IFACEM_IOutArchive(x) \ + x(UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback)) \ + x(GetFileTimeType(UInt32 *type)) -ARCHIVE_INTERFACE(IOutArchive, 0xA0) -{ - INTERFACE_IOutArchive(PURE) -}; +Z7_IFACE_CONSTR_ARCHIVE(IOutArchive, 0xA0) -ARCHIVE_INTERFACE(ISetProperties, 0x03) -{ - STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps) PURE; -}; +/* +ISetProperties::SetProperties() + PROPVARIANT values[i].vt: + VT_EMPTY + VT_BOOL + VT_UI4 - if 32-bit number + VT_UI8 - if 64-bit number + VT_BSTR +*/ -ARCHIVE_INTERFACE(IArchiveKeepModeForNextOpen, 0x04) -{ - STDMETHOD(KeepModeForNextOpen)() PURE; -}; +#define Z7_IFACEM_ISetProperties(x) \ + x(SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)) + +Z7_IFACE_CONSTR_ARCHIVE(ISetProperties, 0x03) + +#define Z7_IFACEM_IArchiveKeepModeForNextOpen(x) \ + x(KeepModeForNextOpen()) \ + +Z7_IFACE_CONSTR_ARCHIVE(IArchiveKeepModeForNextOpen, 0x04) /* Exe handler: the handler for executable format (PE, ELF, Mach-O). SFX archive: executable stub + some tail data. before 9.31: exe handler didn't parse SFX archives as executable format. for 9.31+: exe handler parses SFX archives as executable format, only if AllowTail(1) was called */ -ARCHIVE_INTERFACE(IArchiveAllowTail, 0x05) -{ - STDMETHOD(AllowTail)(Int32 allowTail) PURE; -}; +#define Z7_IFACEM_IArchiveAllowTail(x) \ + x(AllowTail(Int32 allowTail)) \ +Z7_IFACE_CONSTR_ARCHIVE(IArchiveAllowTail, 0x05) -#define IMP_IInArchive_GetProp(k) \ - (UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) \ - { if (index >= ARRAY_SIZE(k)) return E_INVALIDARG; \ - *propID = k[index]; *varType = k7z_PROPID_To_VARTYPE[(unsigned)*propID]; *name = 0; return S_OK; } \ struct CStatProp @@ -528,46 +579,69 @@ namespace NCOM { BSTR AllocBstrFromAscii(const char *s) throw(); }} -#define IMP_IInArchive_GetProp_WITH_NAME(k) \ - (UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) \ - { if (index >= ARRAY_SIZE(k)) return E_INVALIDARG; \ + +#define IMP_IInArchive_GetProp_Base(fn, f, k) \ + Z7_COM7F_IMF(CHandler::fn(UInt32 *numProps)) \ + { *numProps = Z7_ARRAY_SIZE(k); return S_OK; } \ + Z7_COM7F_IMF(CHandler::f(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)) \ + { if (index >= Z7_ARRAY_SIZE(k)) return E_INVALIDARG; \ + +#define IMP_IInArchive_GetProp_NO_NAME(fn, f, k) \ + IMP_IInArchive_GetProp_Base(fn, f, k) \ + *propID = k[index]; \ + *varType = k7z_PROPID_To_VARTYPE[(unsigned)*propID]; \ + *name = NULL; return S_OK; } \ + +#define IMP_IInArchive_GetProp_WITH_NAME(fn, f, k) \ + IMP_IInArchive_GetProp_Base(fn, f, k) \ const CStatProp &prop = k[index]; \ - *propID = (PROPID)prop.PropID; *varType = prop.vt; \ + *propID = (PROPID)prop.PropID; \ + *varType = prop.vt; \ *name = NWindows::NCOM::AllocBstrFromAscii(prop.Name); return S_OK; } \ + #define IMP_IInArchive_Props \ - STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps) \ - { *numProps = ARRAY_SIZE(kProps); return S_OK; } \ - STDMETHODIMP CHandler::GetPropertyInfo IMP_IInArchive_GetProp(kProps) + IMP_IInArchive_GetProp_NO_NAME(GetNumberOfProperties, GetPropertyInfo, kProps) #define IMP_IInArchive_Props_WITH_NAME \ - STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps) \ - { *numProps = ARRAY_SIZE(kProps); return S_OK; } \ - STDMETHODIMP CHandler::GetPropertyInfo IMP_IInArchive_GetProp_WITH_NAME(kProps) - + IMP_IInArchive_GetProp_WITH_NAME(GetNumberOfProperties, GetPropertyInfo, kProps) #define IMP_IInArchive_ArcProps \ - STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProps) \ - { *numProps = ARRAY_SIZE(kArcProps); return S_OK; } \ - STDMETHODIMP CHandler::GetArchivePropertyInfo IMP_IInArchive_GetProp(kArcProps) + IMP_IInArchive_GetProp_NO_NAME(GetNumberOfArchiveProperties, GetArchivePropertyInfo, kArcProps) #define IMP_IInArchive_ArcProps_WITH_NAME \ - STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProps) \ - { *numProps = ARRAY_SIZE(kArcProps); return S_OK; } \ - STDMETHODIMP CHandler::GetArchivePropertyInfo IMP_IInArchive_GetProp_WITH_NAME(kArcProps) + IMP_IInArchive_GetProp_WITH_NAME(GetNumberOfArchiveProperties, GetArchivePropertyInfo, kArcProps) #define IMP_IInArchive_ArcProps_NO_Table \ - STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProps) \ + Z7_COM7F_IMF(CHandler::GetNumberOfArchiveProperties(UInt32 *numProps)) \ { *numProps = 0; return S_OK; } \ - STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32, BSTR *, PROPID *, VARTYPE *) \ + Z7_COM7F_IMF(CHandler::GetArchivePropertyInfo(UInt32, BSTR *, PROPID *, VARTYPE *)) \ { return E_NOTIMPL; } \ #define IMP_IInArchive_ArcProps_NO \ IMP_IInArchive_ArcProps_NO_Table \ - STDMETHODIMP CHandler::GetArchiveProperty(PROPID, PROPVARIANT *value) \ + Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID, PROPVARIANT *value)) \ { value->vt = VT_EMPTY; return S_OK; } +#define Z7_class_CHandler_final \ + Z7_class_final(CHandler) + + +#define Z7_CLASS_IMP_CHandler_IInArchive_0 \ + Z7_CLASS_IMP_COM_1(CHandler, IInArchive) +#define Z7_CLASS_IMP_CHandler_IInArchive_1(i1) \ + Z7_CLASS_IMP_COM_2(CHandler, IInArchive, i1) +#define Z7_CLASS_IMP_CHandler_IInArchive_2(i1, i2) \ + Z7_CLASS_IMP_COM_3(CHandler, IInArchive, i1, i2) +#define Z7_CLASS_IMP_CHandler_IInArchive_3(i1, i2, i3) \ + Z7_CLASS_IMP_COM_4(CHandler, IInArchive, i1, i2, i3) +#define Z7_CLASS_IMP_CHandler_IInArchive_4(i1, i2, i3, i4) \ + Z7_CLASS_IMP_COM_5(CHandler, IInArchive, i1, i2, i3, i4) +#define Z7_CLASS_IMP_CHandler_IInArchive_5(i1, i2, i3, i4, i5) \ + Z7_CLASS_IMP_COM_6(CHandler, IInArchive, i1, i2, i3, i4, i5) + + #define k_IsArc_Res_NO 0 #define k_IsArc_Res_YES 1 @@ -590,9 +664,41 @@ extern "C" typedef HRESULT (WINAPI *Func_SetCaseSensitive)(Int32 caseSensitive); typedef HRESULT (WINAPI *Func_SetLargePageMode)(); + // typedef HRESULT (WINAPI *Func_SetClientVersion)(UInt32 version); typedef IOutArchive * (*Func_CreateOutArchive)(); typedef IInArchive * (*Func_CreateInArchive)(); } + +/* + if there is no time in archive, external MTime of archive + will be used instead of _item.Time from archive. + For 7-zip before 22.00 we need to return some supported value. + But (kpidTimeType > kDOS) is not allowed in 7-Zip before 22.00. + So we return highest precision value supported by old 7-Zip. + new 7-Zip 22.00 doesn't use that value in usual cases. +*/ + + +#define DECLARE_AND_SET_CLIENT_VERSION_VAR +#define GET_FileTimeType_NotDefined_for_GetFileTimeType \ + NFileTimeType::kWindows + +/* +extern UInt32 g_ClientVersion; + +#define GET_CLIENT_VERSION(major, minor) \ + ((UInt32)(((UInt32)(major) << 16) | (UInt32)(minor))) + +#define DECLARE_AND_SET_CLIENT_VERSION_VAR \ + UInt32 g_ClientVersion = GET_CLIENT_VERSION(MY_VER_MAJOR, MY_VER_MINOR); + +#define GET_FileTimeType_NotDefined_for_GetFileTimeType \ + ((UInt32)(g_ClientVersion >= GET_CLIENT_VERSION(22, 0) ? \ + (UInt32)(Int32)NFileTimeType::kNotDefined : \ + NFileTimeType::kWindows)) +*/ + +Z7_PURE_INTERFACES_END #endif diff --git a/3rdparty/lzma/CPP/7zip/Archive/LzmaHandler.cpp b/3rdparty/lzma/CPP/7zip/Archive/LzmaHandler.cpp index 121cd67cee5..11cb76ed467 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/LzmaHandler.cpp +++ b/3rdparty/lzma/CPP/7zip/Archive/LzmaHandler.cpp @@ -44,7 +44,8 @@ static const Byte kProps[] = static const Byte kArcProps[] = { - kpidNumStreams + kpidNumStreams, + kpidMethod }; struct CHeader @@ -53,6 +54,7 @@ struct CHeader Byte FilterID; Byte LzmaProps[5]; + Byte GetProp() const { return LzmaProps[0]; } UInt32 GetDicSize() const { return GetUi32(LzmaProps + 1); } bool HasSize() const { return (Size != (UInt64)(Int64)-1); } bool Parse(const Byte *buf, bool isThereFilter); @@ -74,7 +76,7 @@ bool CHeader::Parse(const Byte *buf, bool isThereFilter) && CheckDicSize(LzmaProps + 1); } -class CDecoder +class CDecoder Z7_final { CMyComPtr<ISequentialOutStream> _bcjStream; CFilterCoder *_filterCoder; @@ -110,7 +112,7 @@ HRESULT CDecoder::Create(bool filteredMode, ISequentialInStream *inStream) { _filterCoder = new CFilterCoder(false); CMyComPtr<ICompressCoder> coder = _filterCoder; - _filterCoder->Filter = new NCompress::NBcj::CCoder(false); + _filterCoder->Filter = new NCompress::NBcj::CCoder2(z7_BranchConvSt_X86_Dec); _bcjStream = _filterCoder; } } @@ -129,21 +131,15 @@ HRESULT CDecoder::Code(const CHeader &header, ISequentialOutStream *outStream, if (header.FilterID > 1) return E_NOTIMPL; - { - CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties; - _lzmaDecoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties); - if (!setDecoderProperties) - return E_NOTIMPL; - RINOK(setDecoderProperties->SetDecoderProperties2(header.LzmaProps, 5)); - } + RINOK(_lzmaDecoderSpec->SetDecoderProperties2(header.LzmaProps, 5)) bool filteredMode = (header.FilterID == 1); if (filteredMode) { - RINOK(_filterCoder->SetOutStream(outStream)); + RINOK(_filterCoder->SetOutStream(outStream)) outStream = _bcjStream; - RINOK(_filterCoder->SetOutStreamSize(NULL)); + RINOK(_filterCoder->SetOutStreamSize(NULL)) } const UInt64 *Size = header.HasSize() ? &header.Size : NULL; @@ -161,7 +157,7 @@ HRESULT CDecoder::Code(const CHeader &header, ISequentialOutStream *outStream, res = res2; } - RINOK(res); + RINOK(res) if (header.HasSize()) if (_lzmaDecoderSpec->GetOutputProcessedSize() != header.Size) @@ -171,11 +167,9 @@ HRESULT CDecoder::Code(const CHeader &header, ISequentialOutStream *outStream, } -class CHandler: - public IInArchive, - public IArchiveOpenSeq, - public CMyUnknownImp -{ +Z7_CLASS_IMP_CHandler_IInArchive_1( + IArchiveOpenSeq +) CHeader _header; bool _lzma86; CMyComPtr<IInStream> _stream; @@ -185,34 +179,28 @@ class CHandler: bool _needSeekToStart; bool _dataAfterEnd; bool _needMoreInput; + bool _unsupported; + bool _dataError; bool _packSize_Defined; bool _unpackSize_Defined; bool _numStreams_Defined; - bool _unsupported; - bool _dataError; - UInt64 _packSize; UInt64 _unpackSize; UInt64 _numStreams; -public: - MY_UNKNOWN_IMP2(IInArchive, IArchiveOpenSeq) - - INTERFACE_IInArchive(;) - STDMETHOD(OpenSeq)(ISequentialInStream *stream); - - CHandler(bool lzma86) { _lzma86 = lzma86; } + void GetMethod(NCOM::CPropVariant &prop); unsigned GetHeaderSize() const { return 5 + 8 + (_lzma86 ? 1 : 0); } - +public: + CHandler(bool lzma86) { _lzma86 = lzma86; } }; IMP_IInArchive_Props IMP_IInArchive_ArcProps -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { NCOM::CPropVariant prop; switch (propID) @@ -220,63 +208,86 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) case kpidPhySize: if (_packSize_Defined) prop = _packSize; break; case kpidNumStreams: if (_numStreams_Defined) prop = _numStreams; break; case kpidUnpackSize: if (_unpackSize_Defined) prop = _unpackSize; break; + case kpidMethod: GetMethod(prop); break; case kpidErrorFlags: { UInt32 v = 0; - if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;; + if (!_isArc) v |= kpv_ErrorFlags_IsNotArc; if (_needMoreInput) v |= kpv_ErrorFlags_UnexpectedEnd; if (_dataAfterEnd) v |= kpv_ErrorFlags_DataAfterEnd; if (_unsupported) v |= kpv_ErrorFlags_UnsupportedMethod; if (_dataError) v |= kpv_ErrorFlags_DataError; prop = v; + break; } } prop.Detach(value); return S_OK; } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = 1; return S_OK; } -static void DictSizeToString(UInt32 value, char *s) + +static char * DictSizeToString(UInt32 val, char *s) { - for (int i = 0; i <= 31; i++) - if (((UInt32)1 << i) == value) - { - ::ConvertUInt32ToString(i, s); - return; - } + for (unsigned i = 0; i < 32; i++) + if (((UInt32)1 << i) == val) + return ::ConvertUInt32ToString(i, s); char c = 'b'; - if ((value & ((1 << 20) - 1)) == 0) { value >>= 20; c = 'm'; } - else if ((value & ((1 << 10) - 1)) == 0) { value >>= 10; c = 'k'; } - ::ConvertUInt32ToString(value, s); - s += MyStringLen(s); + if ((val & ((1 << 20) - 1)) == 0) { val >>= 20; c = 'm'; } + else if ((val & ((1 << 10) - 1)) == 0) { val >>= 10; c = 'k'; } + s = ::ConvertUInt32ToString(val, s); *s++ = c; *s = 0; + return s; +} + +static char *AddProp32(char *s, const char *name, UInt32 v) +{ + *s++ = ':'; + s = MyStpCpy(s, name); + return ::ConvertUInt32ToString(v, s); } -STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) +void CHandler::GetMethod(NCOM::CPropVariant &prop) +{ + if (!_stream) + return; + + char sz[64]; + char *s = sz; + if (_header.FilterID != 0) + s = MyStpCpy(s, "BCJ "); + s = MyStpCpy(s, "LZMA:"); + s = DictSizeToString(_header.GetDicSize(), s); + + UInt32 d = _header.GetProp(); + // if (d != 0x5D) + { + UInt32 lc = d % 9; + d /= 9; + UInt32 pb = d / 5; + UInt32 lp = d % 5; + if (lc != 3) s = AddProp32(s, "lc", lc); + if (lp != 0) s = AddProp32(s, "lp", lp); + if (pb != 2) s = AddProp32(s, "pb", pb); + } + prop = sz; +} + + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)) { NCOM::CPropVariant prop; switch (propID) { case kpidSize: if (_stream && _header.HasSize()) prop = _header.Size; break; case kpidPackSize: if (_packSize_Defined) prop = _packSize; break; - case kpidMethod: - if (_stream) - { - char sz[64]; - char *s = sz; - if (_header.FilterID != 0) - s = MyStpCpy(s, "BCJ "); - s = MyStpCpy(s, "LZMA:"); - DictSizeToString(_header.GetDicSize(), s); - prop = sz; - } - break; + case kpidMethod: GetMethod(prop); break; } prop.Detach(value); return S_OK; @@ -289,10 +300,10 @@ API_FUNC_static_IsArc IsArc_Lzma(const Byte *p, size_t size) return k_IsArc_Res_NEED_MORE; if (p[0] >= 5 * 5 * 9) return k_IsArc_Res_NO; - UInt64 unpackSize = GetUi64(p + 1 + 4); + const UInt64 unpackSize = GetUi64(p + 1 + 4); if (unpackSize != (UInt64)(Int64)-1) { - if (size >= ((UInt64)1 << 56)) + if (unpackSize >= ((UInt64)1 << 56)) return k_IsArc_Res_NO; } if (unpackSize != 0) @@ -325,24 +336,54 @@ API_FUNC_static_IsArc IsArc_Lzma86(const Byte *p, size_t size) } } -STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *) + + +Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *)) { Close(); - const UInt32 kBufSize = 1 + 5 + 8 + 2; + const unsigned headerSize = GetHeaderSize(); + const UInt32 kBufSize = 1 << 7; Byte buf[kBufSize]; - - RINOK(ReadStream_FALSE(inStream, buf, kBufSize)); - + size_t processedSize = kBufSize; + RINOK(ReadStream(inStream, buf, &processedSize)) + if (processedSize < headerSize + 2) + return S_FALSE; if (!_header.Parse(buf, _lzma86)) return S_FALSE; - const Byte *start = buf + GetHeaderSize(); + const Byte *start = buf + headerSize; if (start[0] != 0 /* || (start[1] & 0x80) != 0 */ ) // empty stream with EOS is not 0x80 return S_FALSE; - - RINOK(inStream->Seek(0, STREAM_SEEK_END, &_packSize)); - if (_packSize >= 24 && _header.Size == 0 && _header.FilterID == 0 && _header.LzmaProps[0] == 0) + + RINOK(InStream_GetSize_SeekToEnd(inStream, _packSize)) + + SizeT srcLen = (SizeT)processedSize - headerSize; + + if (srcLen > 10 + && _header.Size == 0 + // && _header.FilterID == 0 + && _header.LzmaProps[0] == 0 + ) return S_FALSE; + + CDecoder state; + const UInt32 outLimit = 1 << 11; + Byte outBuf[outLimit]; + + SizeT outSize = outLimit; + if (outSize > _header.Size) + outSize = (SizeT)_header.Size; + SizeT destLen = outSize; + ELzmaStatus status; + + SRes res = LzmaDecode(outBuf, &destLen, start, &srcLen, + _header.LzmaProps, 5, LZMA_FINISH_ANY, + &status, &g_Alloc); + + if (res != SZ_OK) + if (res != SZ_ERROR_INPUT_EOF) + return S_FALSE; + _isArc = true; _stream = inStream; _seqStream = inStream; @@ -350,7 +391,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCal return S_OK; } -STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream) +Z7_COM7F_IMF(CHandler::OpenSeq(ISequentialInStream *stream)) { Close(); _isArc = true; @@ -358,53 +399,50 @@ STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream) return S_OK; } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _isArc = false; - _packSize_Defined = false; - _unpackSize_Defined = false; - _numStreams_Defined = false; - + _needSeekToStart = false; _dataAfterEnd = false; _needMoreInput = false; _unsupported = false; _dataError = false; - _packSize = 0; + _packSize_Defined = false; + _unpackSize_Defined = false; + _numStreams_Defined = false; - _needSeekToStart = false; + _packSize = 0; _stream.Release(); _seqStream.Release(); return S_OK; } -class CCompressProgressInfoImp: - public ICompressProgressInfo, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_1( + CCompressProgressInfoImp, + ICompressProgressInfo +) CMyComPtr<IArchiveOpenCallback> Callback; public: UInt64 Offset; - - MY_UNKNOWN_IMP1(ICompressProgressInfo) - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); + void Init(IArchiveOpenCallback *callback) { Callback = callback; } }; -STDMETHODIMP CCompressProgressInfoImp::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */) +Z7_COM7F_IMF(CCompressProgressInfoImp::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */)) { if (Callback) { - UInt64 files = 0; - UInt64 value = Offset + *inSize; - return Callback->SetCompleted(&files, &value); + const UInt64 files = 0; + const UInt64 val = Offset + *inSize; + return Callback->SetCompleted(&files, &val); } return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN @@ -418,10 +456,10 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, CMyComPtr<ISequentialOutStream> realOutStream; - Int32 askMode = testMode ? + const Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; - RINOK(extractCallback->GetStream(0, &realOutStream, askMode)); + RINOK(extractCallback->GetStream(0, &realOutStream, askMode)) if (!testMode && !realOutStream) return S_OK; @@ -441,14 +479,14 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, { if (!_stream) return E_FAIL; - RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekToBegin(_stream)) } else _needSeekToStart = true; CDecoder decoder; HRESULT result = decoder.Create(_lzma86, _seqStream); - RINOK(result); + RINOK(result) bool firstItem = true; @@ -462,13 +500,13 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, { lps->InSize = packSize; lps->OutSize = unpackSize; - RINOK(lps->SetCur()); + RINOK(lps->SetCur()) const UInt32 kBufSize = 1 + 5 + 8; Byte buf[kBufSize]; const UInt32 headerSize = GetHeaderSize(); UInt32 processed; - RINOK(decoder.ReadInput(buf, headerSize, &processed)); + RINOK(decoder.ReadInput(buf, headerSize, &processed)) if (processed != headerSize) { if (processed != 0) @@ -498,7 +536,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, } if (result == S_FALSE) break; - RINOK(result); + RINOK(result) } if (firstItem) @@ -510,7 +548,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, { if (dataAfterEnd) _dataAfterEnd = true; - else if (decoder._lzmaDecoderSpec->NeedMoreInput) + else if (decoder._lzmaDecoderSpec->NeedsMoreInput()) _needMoreInput = true; _packSize = packSize; @@ -551,7 +589,7 @@ namespace NLzmaAr { REGISTER_ARC_I_CLS_NO_SIG( CHandler(false), - "lzma", "lzma", 0, 0xA, + "lzma", "lzma", NULL, 0xA, 0, NArcInfoFlags::kStartOpen | NArcInfoFlags::kKeepName, @@ -563,7 +601,7 @@ namespace NLzma86Ar { REGISTER_ARC_I_CLS_NO_SIG( CHandler(true), - "lzma86", "lzma86", 0, 0xB, + "lzma86", "lzma86", NULL, 0xB, 0, NArcInfoFlags::kKeepName, IsArc_Lzma86) diff --git a/3rdparty/lzma/CPP/7zip/Archive/SplitHandler.cpp b/3rdparty/lzma/CPP/7zip/Archive/SplitHandler.cpp index 72b52fe732d..ae7ca0369fb 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/SplitHandler.cpp +++ b/3rdparty/lzma/CPP/7zip/Archive/SplitHandler.cpp @@ -9,6 +9,7 @@ #include "../Common/ProgressUtils.h" #include "../Common/RegisterArc.h" +#include "../Common/StreamUtils.h" #include "../Compress/CopyCoder.h" @@ -31,27 +32,22 @@ static const Byte kArcProps[] = kpidTotalPhySize }; -class CHandler: - public IInArchive, - public IInArchiveGetStream, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_CHandler_IInArchive_1( + IInArchiveGetStream +) CObjectVector<CMyComPtr<IInStream> > _streams; CRecordVector<UInt64> _sizes; UString _subName; UInt64 _totalSize; HRESULT Open2(IInStream *stream, IArchiveOpenCallback *callback); -public: - MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream) - INTERFACE_IInArchive(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); }; IMP_IInArchive_Props IMP_IInArchive_ArcProps -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { NCOM::CPropVariant prop; switch (propID) @@ -121,29 +117,31 @@ struct CSeqName } }; + HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback) { Close(); if (!callback) return S_FALSE; - CMyComPtr<IArchiveOpenVolumeCallback> volumeCallback; - callback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&volumeCallback); + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveOpenVolumeCallback, + volumeCallback, callback) if (!volumeCallback) return S_FALSE; UString name; { NCOM::CPropVariant prop; - RINOK(volumeCallback->GetProperty(kpidName, &prop)); + RINOK(volumeCallback->GetProperty(kpidName, &prop)) if (prop.vt != VT_BSTR) return S_FALSE; name = prop.bstrVal; } - int dotPos = name.ReverseFind_Dot(); - const UString prefix = name.Left(dotPos + 1); - const UString ext = name.Ptr(dotPos + 1); + const int dotPos = name.ReverseFind_Dot(); + const UString prefix = name.Left((unsigned)(dotPos + 1)); + const UString ext = name.Ptr((unsigned)(dotPos + 1)); UString ext2 = ext; ext2.MakeLower_Ascii(); @@ -162,7 +160,10 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback) numLetters++; } } - else if (ext.Len() >= 2 && StringsAreEqual_Ascii(ext2.RightPtr(2), "01")) + else if (ext2.Len() >= 2 && ( + StringsAreEqual_Ascii(ext2.RightPtr(2), "01") + || StringsAreEqual_Ascii(ext2.RightPtr(2), "00") + )) { while (numLetters < ext2.Len()) { @@ -170,7 +171,7 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback) break; numLetters++; } - if (numLetters != ext.Len()) + if (numLetters != ext2.Len()) return S_FALSE; } else @@ -181,7 +182,7 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback) seqName._splitStyle = splitStyle; if (prefix.Len() < 1) - _subName.SetFromAscii("file"); + _subName = "file"; else _subName.SetFrom(prefix, prefix.Len() - 1); @@ -189,14 +190,13 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback) { /* NCOM::CPropVariant prop; - RINOK(volumeCallback->GetProperty(kpidSize, &prop)); + RINOK(volumeCallback->GetProperty(kpidSize, &prop)) if (prop.vt != VT_UI8) return E_INVALIDARG; size = prop.uhVal.QuadPart; */ - RINOK(stream->Seek(0, STREAM_SEEK_END, &size)); - RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); } + RINOK(InStream_AtBegin_GetSize(stream, size)) _totalSize += size; _sizes.Add(size); @@ -204,7 +204,7 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback) { const UInt64 numFiles = _streams.Size(); - RINOK(callback->SetCompleted(&numFiles, NULL)); + RINOK(callback->SetCompleted(&numFiles, NULL)) } for (;;) @@ -213,30 +213,20 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback) if (!seqName.GetNextName(fullName)) break; CMyComPtr<IInStream> nextStream; - HRESULT result = volumeCallback->GetStream(fullName, &nextStream); + const HRESULT result = volumeCallback->GetStream(fullName, &nextStream); if (result == S_FALSE) break; if (result != S_OK) return result; if (!nextStream) break; - { - /* - NCOM::CPropVariant prop; - RINOK(volumeCallback->GetProperty(kpidSize, &prop)); - if (prop.vt != VT_UI8) - return E_INVALIDARG; - size = prop.uhVal.QuadPart; - */ - RINOK(nextStream->Seek(0, STREAM_SEEK_END, &size)); - RINOK(nextStream->Seek(0, STREAM_SEEK_SET, NULL)); - } + RINOK(InStream_AtBegin_GetSize(nextStream, size)) _totalSize += size; _sizes.Add(size); _streams.Add(nextStream); { const UInt64 numFiles = _streams.Size(); - RINOK(callback->SetCompleted(&numFiles, NULL)); + RINOK(callback->SetCompleted(&numFiles, NULL)) } } @@ -248,17 +238,17 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback) return S_OK; } -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback) +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback)) { COM_TRY_BEGIN - HRESULT res = Open2(stream, callback); + const HRESULT res = Open2(stream, callback); if (res != S_OK) Close(); return res; COM_TRY_END } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _totalSize = 0; _subName.Empty(); @@ -267,13 +257,13 @@ STDMETHODIMP CHandler::Close() return S_OK; } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = _streams.IsEmpty() ? 0 : 1; return S_OK; } -STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)) { NCOM::CPropVariant prop; switch (propID) @@ -288,8 +278,8 @@ STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIAN return S_OK; } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN if (numItems == 0) @@ -298,15 +288,15 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, return E_INVALIDARG; UInt64 currentTotalSize = 0; - RINOK(extractCallback->SetTotal(_totalSize)); + RINOK(extractCallback->SetTotal(_totalSize)) CMyComPtr<ISequentialOutStream> outStream; - Int32 askMode = testMode ? + const Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; - RINOK(extractCallback->GetStream(0, &outStream, askMode)); + RINOK(extractCallback->GetStream(0, &outStream, askMode)) if (!testMode && !outStream) return S_OK; - RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->PrepareOperation(askMode)) NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec; @@ -315,13 +305,15 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, CMyComPtr<ICompressProgressInfo> progress = lps; lps->Init(extractCallback, false); - FOR_VECTOR (i, _streams) + for (unsigned i = 0;; i++) { lps->InSize = lps->OutSize = currentTotalSize; - RINOK(lps->SetCur()); + RINOK(lps->SetCur()) + if (i == _streams.Size()) + break; IInStream *inStream = _streams[i]; - RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL)); - RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)); + RINOK(InStream_SeekToBegin(inStream)) + RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)) currentTotalSize += copyCoderSpec->TotalSize; } outStream.Release(); @@ -329,12 +321,12 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, COM_TRY_END } -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) { COM_TRY_BEGIN if (index != 0) return E_INVALIDARG; - *stream = 0; + *stream = NULL; CMultiStream *streamSpec = new CMultiStream; CMyComPtr<ISequentialInStream> streamTemp = streamSpec; FOR_VECTOR (i, _streams) @@ -351,7 +343,7 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) } REGISTER_ARC_I_NO_SIG( - "Split", "001", 0, 0xEA, + "Split", "001", NULL, 0xEA, 0, 0, NULL) diff --git a/3rdparty/lzma/CPP/7zip/Archive/StdAfx.h b/3rdparty/lzma/CPP/7zip/Archive/StdAfx.h index 1cbd7feaeec..80866550d1f 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/StdAfx.h +++ b/3rdparty/lzma/CPP/7zip/Archive/StdAfx.h @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../Common/Common.h" #endif diff --git a/3rdparty/lzma/CPP/7zip/Archive/XzHandler.cpp b/3rdparty/lzma/CPP/7zip/Archive/XzHandler.cpp index 318be190a79..976817c7437 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/XzHandler.cpp +++ b/3rdparty/lzma/CPP/7zip/Archive/XzHandler.cpp @@ -3,16 +3,15 @@ #include "StdAfx.h" #include "../../../C/Alloc.h" -#include "../../../C/XzCrc64.h" -#include "../../../C/XzEnc.h" #include "../../Common/ComTry.h" #include "../../Common/Defs.h" #include "../../Common/IntToString.h" +#include "../../Common/MyBuffer.h" +#include "../../Common/StringToInt.h" #include "../../Windows/PropVariant.h" - -#include "../ICoder.h" +#include "../../Windows/System.h" #include "../Common/CWrappers.h" #include "../Common/ProgressUtils.h" @@ -20,126 +19,174 @@ #include "../Common/StreamUtils.h" #include "../Compress/CopyCoder.h" +#include "../Compress/XzDecoder.h" +#include "../Compress/XzEncoder.h" #include "IArchive.h" -#ifndef EXTRACT_ONLY #include "Common/HandlerOut.h" -#endif - -#include "XzHandler.h" using namespace NWindows; -namespace NCompress { -namespace NLzma2 { - -HRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzma2Props); - -}} - namespace NArchive { namespace NXz { -struct CCrc64Gen { CCrc64Gen() { Crc64GenerateTable(); } } g_Crc64TableInit; +#define k_LZMA2_Name "LZMA2" -static const char *k_LZMA2_Name = "LZMA2"; -void CStatInfo::Clear() +struct CBlockInfo { - InSize = 0; - OutSize = 0; - PhySize = 0; - - NumStreams = 0; - NumBlocks = 0; - - UnpackSize_Defined = false; - - NumStreams_Defined = false; - NumBlocks_Defined = false; - - IsArc = false; - UnexpectedEnd = false; - DataAfterEnd = false; - Unsupported = false; - HeadersError = false; - DataError = false; - CrcError = false; -} + unsigned StreamFlags; + UInt64 PackPos; + UInt64 PackSize; // pure value from Index record, it doesn't include pad zeros + UInt64 UnpackPos; +}; + -class CHandler: +Z7_class_CHandler_final: public IInArchive, public IArchiveOpenSeq, - #ifndef EXTRACT_ONLY - public IOutArchive, + public IInArchiveGetStream, public ISetProperties, - public CMultiMethodProps, - #endif - public CMyUnknownImp + #ifndef Z7_EXTRACT_ONLY + public IOutArchive, + #endif + public CMyUnknownImp, + #ifndef Z7_EXTRACT_ONLY + public CMultiMethodProps + #else + public CCommonMethodProps + #endif { - CStatInfo _stat; + Z7_COM_QI_BEGIN2(IInArchive) + Z7_COM_QI_ENTRY(IArchiveOpenSeq) + Z7_COM_QI_ENTRY(IInArchiveGetStream) + Z7_COM_QI_ENTRY(ISetProperties) + #ifndef Z7_EXTRACT_ONLY + Z7_COM_QI_ENTRY(IOutArchive) + #endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(IInArchive) + Z7_IFACE_COM7_IMP(IArchiveOpenSeq) + Z7_IFACE_COM7_IMP(IInArchiveGetStream) + Z7_IFACE_COM7_IMP(ISetProperties) + #ifndef Z7_EXTRACT_ONLY + Z7_IFACE_COM7_IMP(IOutArchive) + #endif + + CXzStatInfo _stat; // it's stat from backward parsing + CXzStatInfo _stat2; // it's data from forward parsing, if the decoder was called + SRes _stat2_decode_SRes; + bool _stat_defined; + bool _stat2_defined; + + const CXzStatInfo *GetStat() const + { + if (_stat_defined) return &_stat; + if (_stat2_defined) return &_stat2; + return NULL; + } bool _isArc; bool _needSeekToStart; - bool _phySize_Defined; - - CMyComPtr<IInStream> _stream; - CMyComPtr<ISequentialInStream> _seqStream; + bool _firstBlockWasRead; AString _methodsString; - #ifndef EXTRACT_ONLY + + #ifndef Z7_EXTRACT_ONLY UInt32 _filterId; + UInt64 _numSolidBytes; - void Init() + void InitXz() { _filterId = 0; - CMultiMethodProps::Init(); + _numSolidBytes = XZ_PROPS_BLOCK_SIZE_AUTO; } - + #endif + + void Init() + { + #ifndef Z7_EXTRACT_ONLY + InitXz(); + CMultiMethodProps::Init(); + #else + CCommonMethodProps::InitCommon(); + #endif + } + + HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value); + HRESULT Open2(IInStream *inStream, /* UInt32 flags, */ IArchiveOpenCallback *callback); - HRESULT Decode2(ISequentialInStream *seqInStream, ISequentialOutStream *outStream, - CDecoder &decoder, ICompressProgressInfo *progress) + HRESULT Decode(NCompress::NXz::CDecoder &decoder, + ISequentialInStream *seqInStream, + ISequentialOutStream *outStream, + ICompressProgressInfo *progress) { - RINOK(decoder.Decode(seqInStream, outStream, progress)); - _stat = decoder; - _phySize_Defined = true; - return S_OK; + #ifndef Z7_ST + decoder._numThreads = _numThreads; + #endif + decoder._memUsage = _memUsage_Decompress; + + HRESULT hres = decoder.Decode(seqInStream, outStream, + NULL, // *outSizeLimit + true, // finishStream + progress); + + if (decoder.MainDecodeSRes_wasUsed + && decoder.MainDecodeSRes != SZ_ERROR_MEM + && decoder.MainDecodeSRes != SZ_ERROR_UNSUPPORTED) + { + // if (!_stat2_defined) + { + _stat2_decode_SRes = decoder.MainDecodeSRes; + _stat2 = decoder.Stat; + _stat2_defined = true; + } + } + + return hres; } public: - MY_QUERYINTERFACE_BEGIN2(IInArchive) - MY_QUERYINTERFACE_ENTRY(IArchiveOpenSeq) - #ifndef EXTRACT_ONLY - MY_QUERYINTERFACE_ENTRY(IOutArchive) - MY_QUERYINTERFACE_ENTRY(ISetProperties) - #endif - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - INTERFACE_IInArchive(;) - STDMETHOD(OpenSeq)(ISequentialInStream *stream); + CBlockInfo *_blocks; + size_t _blocksArraySize; + UInt64 _maxBlocksSize; + CMyComPtr<IInStream> _stream; + CMyComPtr<ISequentialInStream> _seqStream; - #ifndef EXTRACT_ONLY - INTERFACE_IOutArchive(;) - STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps); - #endif + CXzBlock _firstBlock; CHandler(); + ~CHandler(); + + HRESULT SeekToPackPos(UInt64 pos) + { + return InStream_SeekSet(_stream, pos); + } }; -CHandler::CHandler() + +CHandler::CHandler(): + _blocks(NULL), + _blocksArraySize(0) { - #ifndef EXTRACT_ONLY - Init(); + #ifndef Z7_EXTRACT_ONLY + InitXz(); #endif } +CHandler::~CHandler() +{ + MyFree(_blocks); +} + static const Byte kProps[] = { @@ -152,7 +199,9 @@ static const Byte kArcProps[] = { kpidMethod, kpidNumStreams, - kpidNumBlocks + kpidNumBlocks, + kpidClusterSize, + kpidCharacts }; IMP_IInArchive_Props @@ -169,13 +218,6 @@ static inline void AddHexToString(AString &s, Byte value) s += GetHex(value & 0xF); } -static void AddUInt32ToString(AString &s, UInt32 value) -{ - char temp[16]; - ConvertUInt32ToString(value, temp); - s += temp; -} - static void Lzma2PropToString(AString &s, unsigned prop) { char c = 0; @@ -192,7 +234,7 @@ static void Lzma2PropToString(AString &s, unsigned prop) c = 'm'; } } - AddUInt32ToString(s, size); + s.Add_UInt32(size); if (c != 0) s += c; } @@ -213,13 +255,14 @@ static const CMethodNamePair g_NamePairs[] = { XZ_ID_ARM, "ARM" }, { XZ_ID_ARMT, "ARMT" }, { XZ_ID_SPARC, "SPARC" }, + { XZ_ID_ARM64, "ARM64" }, { XZ_ID_LZMA2, "LZMA2" } }; -static AString GetMethodString(const CXzFilter &f) +static void AddMethodString(AString &s, const CXzFilter &f) { const char *p = NULL; - for (unsigned i = 0; i < ARRAY_SIZE(g_NamePairs); i++) + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_NamePairs); i++) if (g_NamePairs[i].Id == f.id) { p = g_NamePairs[i].Name; @@ -232,7 +275,7 @@ static AString GetMethodString(const CXzFilter &f) p = temp; } - AString s = p; + s += p; if (f.propsSize > 0) { @@ -240,7 +283,9 @@ static AString GetMethodString(const CXzFilter &f) if (f.id == XZ_ID_LZMA2 && f.propsSize == 1) Lzma2PropToString(s, f.props[0]); else if (f.id == XZ_ID_Delta && f.propsSize == 1) - AddUInt32ToString(s, (UInt32)f.props[0] + 1); + s.Add_UInt32((UInt32)f.props[0] + 1); + else if (f.id == XZ_ID_ARM64 && f.propsSize == 1) + s.Add_UInt32((UInt32)f.props[0] + 16 + 2); else { s += '['; @@ -249,13 +294,6 @@ static AString GetMethodString(const CXzFilter &f) s += ']'; } } - return s; -} - -static void AddString(AString &dest, const AString &src) -{ - dest.Add_Space_if_NotEmpty(); - dest += src; } static const char * const kChecks[] = @@ -278,51 +316,76 @@ static const char * const kChecks[] = , NULL }; -static AString GetCheckString(const CXzs &xzs) +static void AddCheckString(AString &s, const CXzs &xzs) { size_t i; UInt32 mask = 0; for (i = 0; i < xzs.num; i++) mask |= ((UInt32)1 << XzFlags_GetCheckType(xzs.streams[i].flags)); - AString s; for (i = 0; i <= XZ_CHECK_MASK; i++) if (((mask >> i) & 1) != 0) { - AString s2; + s.Add_Space_if_NotEmpty(); if (kChecks[i]) - s2 = kChecks[i]; + s += kChecks[i]; else { - s2 = "Check-"; - AddUInt32ToString(s2, (UInt32)i); + s += "Check-"; + s.Add_UInt32((UInt32)i); } - AddString(s, s2); } - return s; } -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; + + const CXzStatInfo *stat = GetStat(); + switch (propID) { - case kpidPhySize: if (_phySize_Defined) prop = _stat.PhySize; break; - case kpidNumStreams: if (_stat.NumStreams_Defined) prop = _stat.NumStreams; break; - case kpidNumBlocks: if (_stat.NumBlocks_Defined) prop = _stat.NumBlocks; break; - case kpidUnpackSize: if (_stat.UnpackSize_Defined) prop = _stat.OutSize; break; + case kpidPhySize: if (stat) prop = stat->InSize; break; + case kpidNumStreams: if (stat && stat->NumStreams_Defined) prop = stat->NumStreams; break; + case kpidNumBlocks: if (stat && stat->NumBlocks_Defined) prop = stat->NumBlocks; break; + case kpidUnpackSize: if (stat && stat->UnpackSize_Defined) prop = stat->OutSize; break; + case kpidClusterSize: if (_stat_defined && _stat.NumBlocks_Defined && stat->NumBlocks > 1) prop = _maxBlocksSize; break; + case kpidCharacts: + if (_firstBlockWasRead) + { + AString s; + if (XzBlock_HasPackSize(&_firstBlock)) + s.Add_OptSpaced("BlockPackSize"); + if (XzBlock_HasUnpackSize(&_firstBlock)) + s.Add_OptSpaced("BlockUnpackSize"); + if (!s.IsEmpty()) + prop = s; + } + break; + + case kpidMethod: if (!_methodsString.IsEmpty()) prop = _methodsString; break; case kpidErrorFlags: { UInt32 v = 0; - if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;; - if (_stat.UnexpectedEnd) v |= kpv_ErrorFlags_UnexpectedEnd; - if (_stat.DataAfterEnd) v |= kpv_ErrorFlags_DataAfterEnd; - if (_stat.HeadersError) v |= kpv_ErrorFlags_HeadersError; - if (_stat.Unsupported) v |= kpv_ErrorFlags_UnsupportedMethod; - if (_stat.DataError) v |= kpv_ErrorFlags_DataError; - if (_stat.CrcError) v |= kpv_ErrorFlags_CrcError; - prop = v; + SRes sres = _stat2_decode_SRes; + if (!_isArc) v |= kpv_ErrorFlags_IsNotArc; + if (sres == SZ_ERROR_INPUT_EOF) v |= kpv_ErrorFlags_UnexpectedEnd; + if (_stat2_defined && _stat2.DataAfterEnd) v |= kpv_ErrorFlags_DataAfterEnd; + if (sres == SZ_ERROR_ARCHIVE) v |= kpv_ErrorFlags_HeadersError; + if (sres == SZ_ERROR_UNSUPPORTED) v |= kpv_ErrorFlags_UnsupportedMethod; + if (sres == SZ_ERROR_DATA) v |= kpv_ErrorFlags_DataError; + if (sres == SZ_ERROR_CRC) v |= kpv_ErrorFlags_CrcError; + if (v != 0) + prop = v; + break; + } + + case kpidMainSubfile: + { + // debug only, comment it: + // if (_blocks) prop = (UInt32)0; + break; } } prop.Detach(value); @@ -330,20 +393,21 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) COM_TRY_END } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = 1; return S_OK; } -STDMETHODIMP CHandler::GetProperty(UInt32, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN + const CXzStatInfo *stat = GetStat(); NCOM::CPropVariant prop; switch (propID) { - case kpidSize: if (_stat.UnpackSize_Defined) prop = _stat.OutSize; break; - case kpidPackSize: if (_phySize_Defined) prop = _stat.PhySize; break; + case kpidSize: if (stat && stat->UnpackSize_Defined) prop = stat->OutSize; break; + case kpidPackSize: if (stat) prop = stat->InSize; break; case kpidMethod: if (!_methodsString.IsEmpty()) prop = _methodsString; break; } prop.Detach(value); @@ -354,27 +418,30 @@ STDMETHODIMP CHandler::GetProperty(UInt32, PROPID propID, PROPVARIANT *value) struct COpenCallbackWrap { - ICompressProgress p; + ICompressProgress vt; IArchiveOpenCallback *OpenCallback; HRESULT Res; - COpenCallbackWrap(IArchiveOpenCallback *progress); + + // new clang shows "non-POD" warning for offsetof(), if we use constructor instead of Init() + void Init(IArchiveOpenCallback *progress); }; -static SRes OpenCallbackProgress(void *pp, UInt64 inSize, UInt64 /* outSize */) +static SRes OpenCallbackProgress(ICompressProgressPtr pp, UInt64 inSize, UInt64 /* outSize */) { - COpenCallbackWrap *p = (COpenCallbackWrap *)pp; + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(COpenCallbackWrap) if (p->OpenCallback) p->Res = p->OpenCallback->SetCompleted(NULL, &inSize); - return (SRes)p->Res; + return HRESULT_To_SRes(p->Res, SZ_ERROR_PROGRESS); } -COpenCallbackWrap::COpenCallbackWrap(IArchiveOpenCallback *callback) +void COpenCallbackWrap::Init(IArchiveOpenCallback *callback) { - p.Progress = OpenCallbackProgress; + vt.Progress = OpenCallbackProgress; OpenCallback = callback; Res = SZ_OK; } + struct CXzsCPP { CXzs p; @@ -382,6 +449,30 @@ struct CXzsCPP ~CXzsCPP() { Xzs_Free(&p, &g_Alloc); } }; +#define kInputBufSize ((size_t)1 << 10) + +struct CLookToRead2_CPP: public CLookToRead2 +{ + CLookToRead2_CPP() + { + buf = NULL; + LookToRead2_CreateVTable(this, + True // Lookahead ? + ); + } + void Alloc(size_t allocSize) + { + buf = (Byte *)MyAlloc(allocSize); + if (buf) + this->bufSize = allocSize; + } + ~CLookToRead2_CPP() + { + MyFree(buf); + } +}; + + static HRESULT SRes_to_Open_HRESULT(SRes res) { switch (res) @@ -401,49 +492,90 @@ static HRESULT SRes_to_Open_HRESULT(SRes res) return S_FALSE; } + + HRESULT CHandler::Open2(IInStream *inStream, /* UInt32 flags, */ IArchiveOpenCallback *callback) { _needSeekToStart = true; { CXzStreamFlags st; - CSeqInStreamWrap inStreamWrap(inStream); - SRes res = Xz_ReadHeader(&st, &inStreamWrap.p); + CSeqInStreamWrap inStreamWrap; + + inStreamWrap.Init(inStream); + + SRes res = Xz_ReadHeader(&st, &inStreamWrap.vt); + + if (inStreamWrap.Res != S_OK) + return inStreamWrap.Res; if (res != SZ_OK) return SRes_to_Open_HRESULT(res); { CXzBlock block; - Bool isIndex; + BoolInt isIndex; UInt32 headerSizeRes; - SRes res2 = XzBlock_ReadHeader(&block, &inStreamWrap.p, &isIndex, &headerSizeRes); - if (res2 == SZ_OK && !isIndex) + + SRes res2 = XzBlock_ReadHeader(&block, &inStreamWrap.vt, &isIndex, &headerSizeRes); + + if (inStreamWrap.Res != S_OK) + return inStreamWrap.Res; + + if (res2 != SZ_OK) { + if (res2 == SZ_ERROR_INPUT_EOF) + { + _stat2_decode_SRes = res2; + _stream = inStream; + _seqStream = inStream; + _isArc = true; + return S_OK; + } + + if (res2 == SZ_ERROR_ARCHIVE) + return S_FALSE; + } + else if (!isIndex) + { + _firstBlockWasRead = true; + _firstBlock = block; + unsigned numFilters = XzBlock_GetNumFilters(&block); for (unsigned i = 0; i < numFilters; i++) - AddString(_methodsString, GetMethodString(block.filters[i])); + { + _methodsString.Add_Space_if_NotEmpty(); + AddMethodString(_methodsString, block.filters[i]); + } } } } - RINOK(inStream->Seek(0, STREAM_SEEK_END, &_stat.PhySize)); + RINOK(InStream_GetSize_SeekToEnd(inStream, _stat.InSize)) if (callback) { - RINOK(callback->SetTotal(NULL, &_stat.PhySize)); + RINOK(callback->SetTotal(NULL, &_stat.InSize)) } - CSeekInStreamWrap inStreamImp(inStream); + CSeekInStreamWrap inStreamImp; + + inStreamImp.Init(inStream); + + CLookToRead2_CPP lookStream; + + lookStream.Alloc(kInputBufSize); + + if (!lookStream.buf) + return E_OUTOFMEMORY; - CLookToRead lookStream; - LookToRead_CreateVTable(&lookStream, True); - lookStream.realStream = &inStreamImp.p; - LookToRead_Init(&lookStream); + lookStream.realStream = &inStreamImp.vt; + LookToRead2_INIT(&lookStream) - COpenCallbackWrap openWrap(callback); + COpenCallbackWrap openWrap; + openWrap.Init(callback); CXzsCPP xzs; Int64 startPosition; - SRes res = Xzs_ReadBackward(&xzs.p, &lookStream.s, &startPosition, &openWrap.p, &g_Alloc); + SRes res = Xzs_ReadBackward(&xzs.p, &lookStream.vt, &startPosition, &openWrap.vt, &g_Alloc); if (res == SZ_ERROR_PROGRESS) return (openWrap.Res == S_OK) ? E_FAIL : openWrap.Res; /* @@ -452,7 +584,7 @@ HRESULT CHandler::Open2(IInStream *inStream, /* UInt32 flags, */ IArchiveOpenCal */ if (res == SZ_OK && startPosition == 0) { - _phySize_Defined = true; + _stat_defined = true; _stat.OutSize = Xzs_GetUnpackSize(&xzs.p); _stat.UnpackSize_Defined = true; @@ -463,21 +595,81 @@ HRESULT CHandler::Open2(IInStream *inStream, /* UInt32 flags, */ IArchiveOpenCal _stat.NumBlocks = Xzs_GetNumBlocks(&xzs.p); _stat.NumBlocks_Defined = true; - AddString(_methodsString, GetCheckString(xzs.p)); + AddCheckString(_methodsString, xzs.p); + + const size_t numBlocks = (size_t)_stat.NumBlocks + 1; + const size_t bytesAlloc = numBlocks * sizeof(CBlockInfo); + + if (bytesAlloc / sizeof(CBlockInfo) == _stat.NumBlocks + 1) + { + _blocks = (CBlockInfo *)MyAlloc(bytesAlloc); + if (_blocks) + { + unsigned blockIndex = 0; + UInt64 unpackPos = 0; + + for (size_t si = xzs.p.num; si != 0;) + { + si--; + const CXzStream &str = xzs.p.streams[si]; + UInt64 packPos = str.startOffset + XZ_STREAM_HEADER_SIZE; + + for (size_t bi = 0; bi < str.numBlocks; bi++) + { + const CXzBlockSizes &bs = str.blocks[bi]; + const UInt64 packSizeAligned = bs.totalSize + ((0 - (unsigned)bs.totalSize) & 3); + + if (bs.unpackSize != 0) + { + if (blockIndex >= _stat.NumBlocks) + return E_FAIL; + + CBlockInfo &block = _blocks[blockIndex++]; + block.StreamFlags = str.flags; + block.PackSize = bs.totalSize; // packSizeAligned; + block.PackPos = packPos; + block.UnpackPos = unpackPos; + } + packPos += packSizeAligned; + unpackPos += bs.unpackSize; + if (_maxBlocksSize < bs.unpackSize) + _maxBlocksSize = bs.unpackSize; + } + } + + /* + if (blockIndex != _stat.NumBlocks) + { + // there are Empty blocks; + } + */ + if (_stat.OutSize != unpackPos) + return E_FAIL; + CBlockInfo &block = _blocks[blockIndex++]; + block.StreamFlags = 0; + block.PackSize = 0; + block.PackPos = 0; + block.UnpackPos = unpackPos; + _blocksArraySize = blockIndex; + } + } } else { res = SZ_OK; } - RINOK(SRes_to_Open_HRESULT(res)); + RINOK(SRes_to_Open_HRESULT(res)) + _stream = inStream; _seqStream = inStream; _isArc = true; return S_OK; } -STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *callback) + + +Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *callback)) { COM_TRY_BEGIN { @@ -487,7 +679,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCal COM_TRY_END } -STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream) +Z7_COM7F_IMF(CHandler::OpenSeq(ISequentialInStream *stream)) { Close(); _seqStream = stream; @@ -496,206 +688,340 @@ STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream) return S_OK; } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { - _stat.Clear(); + XzStatInfo_Clear(&_stat); + XzStatInfo_Clear(&_stat2); + _stat_defined = false; + _stat2_defined = false; + _stat2_decode_SRes = SZ_OK; _isArc = false; _needSeekToStart = false; + _firstBlockWasRead = false; - _phySize_Defined = false; - _methodsString.Empty(); _stream.Release(); _seqStream.Release(); + + MyFree(_blocks); + _blocks = NULL; + _blocksArraySize = 0; + _maxBlocksSize = 0; + return S_OK; } -class CSeekToSeqStream: - public IInStream, - public CMyUnknownImp -{ -public: - CMyComPtr<ISequentialInStream> Stream; - MY_UNKNOWN_IMP1(IInStream) - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); +struct CXzUnpackerCPP2 +{ + Byte *InBuf; + // Byte *OutBuf; + CXzUnpacker p; + + CXzUnpackerCPP2(); + ~CXzUnpackerCPP2(); }; -STDMETHODIMP CSeekToSeqStream::Read(void *data, UInt32 size, UInt32 *processedSize) +CXzUnpackerCPP2::CXzUnpackerCPP2(): InBuf(NULL) + // , OutBuf(NULL) { - return Stream->Read(data, size, processedSize); + XzUnpacker_Construct(&p, &g_Alloc); } -STDMETHODIMP CSeekToSeqStream::Seek(Int64, UInt32, UInt64 *) { return E_NOTIMPL; } - -CXzUnpackerCPP::CXzUnpackerCPP(): InBuf(0), OutBuf(0) +CXzUnpackerCPP2::~CXzUnpackerCPP2() { - XzUnpacker_Construct(&p, &g_Alloc); + XzUnpacker_Free(&p); + MidFree(InBuf); + // MidFree(OutBuf); } -CXzUnpackerCPP::~CXzUnpackerCPP() + +Z7_CLASS_IMP_COM_1( + CInStream + , IInStream +) + Z7_IFACE_COM7_IMP(ISequentialInStream) + + UInt64 _virtPos; +public: + UInt64 Size; + UInt64 _cacheStartPos; + size_t _cacheSize; + CByteBuffer _cache; + // UInt64 _startPos; + CXzUnpackerCPP2 xz; + + void InitAndSeek() + { + _virtPos = 0; + _cacheStartPos = 0; + _cacheSize = 0; + // _startPos = startPos; + } + + CHandler *_handlerSpec; + CMyComPtr<IUnknown> _handler; + + // ~CInStream(); +}; + +/* +CInStream::~CInStream() { - XzUnpacker_Free(&p); - MyFree(InBuf); - MyFree(OutBuf); + // _cache.Free(); } +*/ -HRESULT CDecoder::Decode(ISequentialInStream *seqInStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress) +static size_t FindBlock(const CBlockInfo *blocks, size_t numBlocks, UInt64 pos) { - const size_t kInBufSize = 1 << 15; - const size_t kOutBufSize = 1 << 21; + size_t left = 0, right = numBlocks; + for (;;) + { + size_t mid = (left + right) / 2; + if (mid == left) + return left; + if (pos < blocks[mid].UnpackPos) + right = mid; + else + left = mid; + } +} + - Clear(); - DecodeRes = SZ_OK; + +static HRESULT DecodeBlock(CXzUnpackerCPP2 &xzu, + ISequentialInStream *seqInStream, + unsigned streamFlags, + UInt64 packSize, // pure size from Index record, it doesn't include pad zeros + size_t unpackSize, Byte *dest + // , ICompressProgressInfo *progress + ) +{ + const size_t kInBufSize = (size_t)1 << 16; XzUnpacker_Init(&xzu.p); + if (!xzu.InBuf) - xzu.InBuf = (Byte *)MyAlloc(kInBufSize); - if (!xzu.OutBuf) - xzu.OutBuf = (Byte *)MyAlloc(kOutBufSize); + { + xzu.InBuf = (Byte *)MidAlloc(kInBufSize); + if (!xzu.InBuf) + return E_OUTOFMEMORY; + } + xzu.p.streamFlags = (UInt16)streamFlags; + XzUnpacker_PrepareToRandomBlockDecoding(&xzu.p); + + XzUnpacker_SetOutBuf(&xzu.p, dest, unpackSize); + + const UInt64 packSizeAligned = packSize + ((0 - (unsigned)packSize) & 3); + UInt64 packRem = packSizeAligned; + UInt32 inSize = 0; SizeT inPos = 0; SizeT outPos = 0; + HRESULT readRes = S_OK; + for (;;) { - if (inPos == inSize) + if (inPos == inSize && readRes == S_OK) { - inPos = inSize = 0; - RINOK(seqInStream->Read(xzu.InBuf, kInBufSize, &inSize)); + inPos = 0; + inSize = 0; + UInt32 rem = kInBufSize; + if (rem > packRem) + rem = (UInt32)packRem; + if (rem != 0) + readRes = seqInStream->Read(xzu.InBuf, rem, &inSize); } SizeT inLen = inSize - inPos; - SizeT outLen = kOutBufSize - outPos; - ECoderStatus status; + SizeT outLen = unpackSize - outPos; - SRes res = XzUnpacker_Code(&xzu.p, - xzu.OutBuf + outPos, &outLen, + ECoderStatus status; + + const SRes res = XzUnpacker_Code(&xzu.p, + // dest + outPos, + NULL, + &outLen, xzu.InBuf + inPos, &inLen, - (inSize == 0 ? CODER_FINISH_END : CODER_FINISH_ANY), &status); + (inLen == 0), // srcFinished + CODER_FINISH_END, &status); - inPos += inLen; - outPos += outLen; + // return E_OUTOFMEMORY; + // res = SZ_ERROR_CRC; - InSize += inLen; - OutSize += outLen; + if (res != SZ_OK) + { + if (res == SZ_ERROR_CRC) + return S_FALSE; + return SResToHRESULT(res); + } - DecodeRes = res; + inPos += inLen; + outPos += outLen; - bool finished = ((inLen == 0 && outLen == 0) || res != SZ_OK); + packRem -= inLen; + + const BoolInt blockFinished = XzUnpacker_IsBlockFinished(&xzu.p); - if (outStream) + if ((inLen == 0 && outLen == 0) || blockFinished) { - if (outPos == kOutBufSize || finished) - { - if (outPos != 0) - { - RINOK(WriteStream(outStream, xzu.OutBuf, outPos)); - outPos = 0; - } - } + if (packRem != 0 || !blockFinished || unpackSize != outPos) + return S_FALSE; + if (XzUnpacker_GetPackSizeForIndex(&xzu.p) != packSize) + return S_FALSE; + return S_OK; } - else - outPos = 0; - - if (progress) + } +} + + +Z7_COM7F_IMF(CInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + COM_TRY_BEGIN + + if (processedSize) + *processedSize = 0; + if (size == 0) + return S_OK; + + { + if (_virtPos >= Size) + return S_OK; // (Size == _virtPos) ? S_OK: E_FAIL; { - RINOK(progress->SetRatioInfo(&InSize, &OutSize)); + UInt64 rem = Size - _virtPos; + if (size > rem) + size = (UInt32)rem; } - - if (finished) - { - PhySize = InSize; - NumStreams = xzu.p.numStartedStreams; - if (NumStreams > 0) - IsArc = true; - NumBlocks = xzu.p.numTotalBlocks; + } - UnpackSize_Defined = true; - NumStreams_Defined = true; - NumBlocks_Defined = true; + if (size == 0) + return S_OK; - UInt64 extraSize = XzUnpacker_GetExtraSize(&xzu.p); + if (_virtPos < _cacheStartPos || _virtPos >= _cacheStartPos + _cacheSize) + { + const size_t bi = FindBlock(_handlerSpec->_blocks, _handlerSpec->_blocksArraySize, _virtPos); + const CBlockInfo &block = _handlerSpec->_blocks[bi]; + const UInt64 unpackSize = _handlerSpec->_blocks[bi + 1].UnpackPos - block.UnpackPos; + if (_cache.Size() < unpackSize) + return E_FAIL; - if (res == SZ_OK) - { - if (status == CODER_STATUS_NEEDS_MORE_INPUT) - { - extraSize = 0; - if (!XzUnpacker_IsStreamWasFinished(&xzu.p)) - { - // finished at padding bytes, but padding is not aligned for 4 - UnexpectedEnd = true; - res = SZ_ERROR_DATA; - } - } - else // status == CODER_STATUS_NOT_FINISHED - res = SZ_ERROR_DATA; - } - else if (res == SZ_ERROR_NO_ARCHIVE) - { - if (InSize == extraSize) - IsArc = false; - else - { - if (extraSize != 0 || inPos != inSize) - { - DataAfterEnd = true; - res = SZ_OK; - } - } - } + _cacheSize = 0; - DecodeRes = res; - PhySize -= extraSize; + RINOK(_handlerSpec->SeekToPackPos(block.PackPos)) + RINOK(DecodeBlock(xz, _handlerSpec->_seqStream, block.StreamFlags, block.PackSize, + (size_t)unpackSize, _cache)) + _cacheStartPos = block.UnpackPos; + _cacheSize = (size_t)unpackSize; + } - switch (res) - { - case SZ_OK: break; - case SZ_ERROR_NO_ARCHIVE: IsArc = false; break; - case SZ_ERROR_ARCHIVE: HeadersError = true; break; - case SZ_ERROR_UNSUPPORTED: Unsupported = true; break; - case SZ_ERROR_CRC: CrcError = true; break; - case SZ_ERROR_DATA: DataError = true; break; - default: DataError = true; break; - } + { + const size_t offset = (size_t)(_virtPos - _cacheStartPos); + const size_t rem = _cacheSize - offset; + if (size > rem) + size = (UInt32)rem; + memcpy(data, _cache + offset, size); + _virtPos += size; + if (processedSize) + *processedSize = size; + return S_OK; + } - break; - } + COM_TRY_END +} + + +Z7_COM7F_IMF(CInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) +{ + switch (seekOrigin) + { + case STREAM_SEEK_SET: break; + case STREAM_SEEK_CUR: offset += _virtPos; break; + case STREAM_SEEK_END: offset += Size; break; + default: return STG_E_INVALIDFUNCTION; } + if (offset < 0) + return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; + _virtPos = (UInt64)offset; + if (newPosition) + *newPosition = (UInt64)offset; + return S_OK; +} + + + +static const UInt64 kMaxBlockSize_for_GetStream = (UInt64)1 << 40; + +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) +{ + COM_TRY_BEGIN + + *stream = NULL; + + if (index != 0) + return E_INVALIDARG; + + if (!_stat.UnpackSize_Defined + || _maxBlocksSize == 0 // 18.02 + || _maxBlocksSize > kMaxBlockSize_for_GetStream + || _maxBlocksSize != (size_t)_maxBlocksSize) + return S_FALSE; + UInt64 memSize; + if (!NSystem::GetRamSize(memSize)) + memSize = (UInt64)(sizeof(size_t)) << 28; + { + if (_maxBlocksSize > memSize / 4) + return S_FALSE; + } + + CInStream *spec = new CInStream; + CMyComPtr<ISequentialInStream> specStream = spec; + spec->_cache.Alloc((size_t)_maxBlocksSize); + spec->_handlerSpec = this; + spec->_handler = (IInArchive *)this; + spec->Size = _stat.OutSize; + spec->InitAndSeek(); + + *stream = specStream.Detach(); return S_OK; + + COM_TRY_END } -Int32 CDecoder::Get_Extract_OperationResult() const + +static Int32 Get_Extract_OperationResult(const NCompress::NXz::CDecoder &decoder) { Int32 opRes; - if (!IsArc) + SRes sres = decoder.MainDecodeSRes; + if (sres == SZ_ERROR_NO_ARCHIVE) // (!IsArc) opRes = NExtract::NOperationResult::kIsNotArc; - else if (UnexpectedEnd) + else if (sres == SZ_ERROR_INPUT_EOF) // (UnexpectedEnd) opRes = NExtract::NOperationResult::kUnexpectedEnd; - else if (DataAfterEnd) + else if (decoder.Stat.DataAfterEnd) opRes = NExtract::NOperationResult::kDataAfterEnd; - else if (CrcError) + else if (sres == SZ_ERROR_CRC) // (CrcError) opRes = NExtract::NOperationResult::kCRCError; - else if (Unsupported) + else if (sres == SZ_ERROR_UNSUPPORTED) // (Unsupported) opRes = NExtract::NOperationResult::kUnsupportedMethod; - else if (HeadersError) + else if (sres == SZ_ERROR_ARCHIVE) // (HeadersError) opRes = NExtract::NOperationResult::kDataError; - else if (DataError) + else if (sres == SZ_ERROR_DATA) // (DataError) opRes = NExtract::NOperationResult::kDataError; - else if (DecodeRes != SZ_OK) + else if (sres != SZ_OK) opRes = NExtract::NOperationResult::kDataError; else opRes = NExtract::NOperationResult::kOK; return opRes; } -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) + + + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN if (numItems == 0) @@ -703,17 +1029,19 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0)) return E_INVALIDARG; - if (_phySize_Defined) - extractCallback->SetTotal(_stat.PhySize); + const CXzStatInfo *stat = GetStat(); + + if (stat) + extractCallback->SetTotal(stat->InSize); UInt64 currentTotalPacked = 0; - RINOK(extractCallback->SetCompleted(¤tTotalPacked)); + RINOK(extractCallback->SetCompleted(¤tTotalPacked)) CMyComPtr<ISequentialOutStream> realOutStream; - Int32 askMode = testMode ? + const Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; - RINOK(extractCallback->GetStream(0, &realOutStream, askMode)); + RINOK(extractCallback->GetStream(0, &realOutStream, askMode)) if (!testMode && !realOutStream) return S_OK; @@ -728,55 +1056,76 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, { if (!_stream) return E_FAIL; - RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekToBegin(_stream)) } else _needSeekToStart = true; - CDecoder decoder; - RINOK(Decode2(_seqStream, realOutStream, decoder, lpsRef)); - Int32 opRes = decoder.Get_Extract_OperationResult(); + + NCompress::NXz::CDecoder decoder; + + HRESULT hres = Decode(decoder, _seqStream, realOutStream, lpsRef); + + if (!decoder.MainDecodeSRes_wasUsed) + return hres == S_OK ? E_FAIL : hres; + + Int32 opRes = Get_Extract_OperationResult(decoder); + if (opRes == NExtract::NOperationResult::kOK + && hres != S_OK) + opRes = NExtract::NOperationResult::kDataError; realOutStream.Release(); return extractCallback->SetOperationResult(opRes); COM_TRY_END } -#ifndef EXTRACT_ONLY -STDMETHODIMP CHandler::GetFileTimeType(UInt32 *timeType) + +#ifndef Z7_EXTRACT_ONLY + +Z7_COM7F_IMF(CHandler::GetFileTimeType(UInt32 *timeType)) { - *timeType = NFileTimeType::kUnix; + *timeType = GET_FileTimeType_NotDefined_for_GetFileTimeType; + // *timeType = NFileTimeType::kUnix; return S_OK; } -STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, - IArchiveUpdateCallback *updateCallback) + +Z7_COM7F_IMF(CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, + IArchiveUpdateCallback *updateCallback)) { COM_TRY_BEGIN - CSeqOutStreamWrap seqOutStream(outStream); - if (numItems == 0) { - SRes res = Xz_EncodeEmpty(&seqOutStream.p); + CSeqOutStreamWrap seqOutStream; + seqOutStream.Init(outStream); + SRes res = Xz_EncodeEmpty(&seqOutStream.vt); return SResToHRESULT(res); } if (numItems != 1) return E_INVALIDARG; + { + Z7_DECL_CMyComPtr_QI_FROM( + IStreamSetRestriction, + setRestriction, outStream) + if (setRestriction) + RINOK(setRestriction->SetRestriction(0, 0)) + } + Int32 newData, newProps; UInt32 indexInArchive; if (!updateCallback) return E_FAIL; - RINOK(updateCallback->GetUpdateItemInfo(0, &newData, &newProps, &indexInArchive)); + RINOK(updateCallback->GetUpdateItemInfo(0, &newData, &newProps, &indexInArchive)) if (IntToBool(newProps)) { { NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(0, kpidIsDir, &prop)); + RINOK(updateCallback->GetProperty(0, kpidIsDir, &prop)) if (prop.vt != VT_EMPTY) if (prop.vt != VT_BOOL || prop.boolVal != VARIANT_FALSE) return E_INVALIDARG; @@ -785,101 +1134,173 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt if (IntToBool(newData)) { - UInt64 size; + UInt64 dataSize; { NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(0, kpidSize, &prop)); + RINOK(updateCallback->GetProperty(0, kpidSize, &prop)) if (prop.vt != VT_UI8) return E_INVALIDARG; - size = prop.uhVal.QuadPart; - RINOK(updateCallback->SetTotal(size)); + dataSize = prop.uhVal.QuadPart; } - CLzma2EncProps lzma2Props; - Lzma2EncProps_Init(&lzma2Props); - - lzma2Props.lzmaProps.level = GetLevel(); + NCompress::NXz::CEncoder *encoderSpec = new NCompress::NXz::CEncoder; + CMyComPtr<ICompressCoder> encoder = encoderSpec; - CMyComPtr<ISequentialInStream> fileInStream; - RINOK(updateCallback->GetStream(0, &fileInStream)); + CXzProps &xzProps = encoderSpec->xzProps; + CLzma2EncProps &lzma2Props = xzProps.lzma2Props; - CSeqInStreamWrap seqInStream(fileInStream); + lzma2Props.lzmaProps.level = GetLevel(); + xzProps.reduceSize = dataSize; + /* { - NCOM::CPropVariant prop = (UInt64)size; - RINOK(NCompress::NLzma2::SetLzma2Prop(NCoderPropID::kReduceSize, prop, lzma2Props)); + NCOM::CPropVariant prop = (UInt64)dataSize; + RINOK(encoderSpec->SetCoderProp(NCoderPropID::kReduceSize, prop)) } + */ - FOR_VECTOR (i, _methods) + #ifndef Z7_ST + + UInt32 numThreads = _numThreads; + + const UInt32 kNumThreads_Max = 1024; + if (numThreads > kNumThreads_Max) + numThreads = kNumThreads_Max; + + if (!_numThreads_WasForced + && _numThreads >= 1 + && _memUsage_WasSet) { - COneMethodInfo &m = _methods[i]; - SetGlobalLevelAndThreads(m - #ifndef _7ZIP_ST - , _numThreads - #endif - ); + COneMethodInfo oneMethodInfo; + if (!_methods.IsEmpty()) + oneMethodInfo = _methods[0]; + + SetGlobalLevelTo(oneMethodInfo); + + const bool numThreads_WasSpecifiedInMethod = (oneMethodInfo.Get_NumThreads() >= 0); + if (!numThreads_WasSpecifiedInMethod) { - FOR_VECTOR (j, m.Props) + // here we set the (NCoderPropID::kNumThreads) property in each method, only if there is no such property already + CMultiMethodProps::SetMethodThreadsTo_IfNotFinded(oneMethodInfo, numThreads); + } + + UInt64 cs = _numSolidBytes; + if (cs != XZ_PROPS_BLOCK_SIZE_AUTO) + oneMethodInfo.AddProp_BlockSize2(cs); + cs = oneMethodInfo.Get_Xz_BlockSize(); + + if (cs != XZ_PROPS_BLOCK_SIZE_AUTO && + cs != XZ_PROPS_BLOCK_SIZE_SOLID) + { + const UInt32 lzmaThreads = oneMethodInfo.Get_Lzma_NumThreads(); + const UInt32 numBlockThreads_Original = numThreads / lzmaThreads; + + if (numBlockThreads_Original > 1) { - const CProp &prop = m.Props[j]; - RINOK(NCompress::NLzma2::SetLzma2Prop(prop.Id, prop.Value, lzma2Props)); + UInt32 numBlockThreads = numBlockThreads_Original; + { + const UInt64 lzmaMemUsage = oneMethodInfo.Get_Lzma_MemUsage(false); + for (; numBlockThreads > 1; numBlockThreads--) + { + UInt64 size = numBlockThreads * (lzmaMemUsage + cs); + UInt32 numPackChunks = numBlockThreads + (numBlockThreads / 8) + 1; + if (cs < ((UInt32)1 << 26)) numPackChunks++; + if (cs < ((UInt32)1 << 24)) numPackChunks++; + if (cs < ((UInt32)1 << 22)) numPackChunks++; + size += numPackChunks * cs; + // printf("\nnumBlockThreads = %d, size = %d\n", (unsigned)(numBlockThreads), (unsigned)(size >> 20)); + if (size <= _memUsage_Compress) + break; + } + } + if (numBlockThreads == 0) + numBlockThreads = 1; + if (numBlockThreads != numBlockThreads_Original) + numThreads = numBlockThreads * lzmaThreads; } } } + xzProps.numTotalThreads = (int)numThreads; - #ifndef _7ZIP_ST - lzma2Props.numTotalThreads = _numThreads; - #endif + #endif // Z7_ST - CLocalProgress *lps = new CLocalProgress; - CMyComPtr<ICompressProgressInfo> progress = lps; - lps->Init(updateCallback, true); - - CCompressProgressWrap progressWrap(progress); - CXzProps xzProps; - CXzFilterProps filter; - XzProps_Init(&xzProps); - XzFilterProps_Init(&filter); - xzProps.lzma2Props = &lzma2Props; - xzProps.filterProps = (_filterId != 0 ? &filter : NULL); - switch (_crcSize) + + xzProps.blockSize = _numSolidBytes; + if (_numSolidBytes == XZ_PROPS_BLOCK_SIZE_SOLID) { - case 0: xzProps.checkId = XZ_CHECK_NO; break; - case 4: xzProps.checkId = XZ_CHECK_CRC32; break; - case 8: xzProps.checkId = XZ_CHECK_CRC64; break; - case 32: xzProps.checkId = XZ_CHECK_SHA256; break; - default: return E_INVALIDARG; + xzProps.lzma2Props.blockSize = LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID; } - filter.id = _filterId; - if (_filterId == XZ_ID_Delta) + + RINOK(encoderSpec->SetCheckSize(_crcSize)) + { - bool deltaDefined = false; - FOR_VECTOR (j, _filterMethod.Props) + CXzFilterProps &filter = xzProps.filterProps; + + if (_filterId == XZ_ID_Delta) { - const CProp &prop = _filterMethod.Props[j]; - if (prop.Id == NCoderPropID::kDefaultProp && prop.Value.vt == VT_UI4) + bool deltaDefined = false; + FOR_VECTOR (j, _filterMethod.Props) { - UInt32 delta = (UInt32)prop.Value.ulVal; - if (delta < 1 || delta > 256) + const CProp &prop = _filterMethod.Props[j]; + if (prop.Id == NCoderPropID::kDefaultProp && prop.Value.vt == VT_UI4) + { + UInt32 delta = (UInt32)prop.Value.ulVal; + if (delta < 1 || delta > 256) + return E_INVALIDARG; + filter.delta = delta; + deltaDefined = true; + } + else return E_INVALIDARG; - filter.delta = delta; - deltaDefined = true; } + if (!deltaDefined) + return E_INVALIDARG; } - if (!deltaDefined) - return E_INVALIDARG; + filter.id = _filterId; } - SRes res = Xz_Encode(&seqOutStream.p, &seqInStream.p, &xzProps, &progressWrap.p); - if (res == SZ_OK) - return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK); - return SResToHRESULT(res); + + FOR_VECTOR (i, _methods) + { + COneMethodInfo &m = _methods[i]; + + FOR_VECTOR (j, m.Props) + { + const CProp &prop = m.Props[j]; + RINOK(encoderSpec->SetCoderProp(prop.Id, prop.Value)) + } + } + + { + CMyComPtr<ISequentialInStream> fileInStream; + RINOK(updateCallback->GetStream(0, &fileInStream)) + if (!fileInStream) + return S_FALSE; + { + CMyComPtr<IStreamGetSize> streamGetSize; + fileInStream.QueryInterface(IID_IStreamGetSize, &streamGetSize); + if (streamGetSize) + { + UInt64 size; + if (streamGetSize->GetSize(&size) == S_OK) + dataSize = size; + } + } + RINOK(updateCallback->SetTotal(dataSize)) + CLocalProgress *lps = new CLocalProgress; + CMyComPtr<ICompressProgressInfo> progress = lps; + lps->Init(updateCallback, true); + RINOK(encoder->Code(fileInStream, outStream, NULL, NULL, progress)) + } + + return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK); } if (indexInArchive != 0) return E_INVALIDARG; - CMyComPtr<IArchiveUpdateCallbackFile> opCallback; - updateCallback->QueryInterface(IID_IArchiveUpdateCallbackFile, (void **)&opCallback); + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveUpdateCallbackFile, + opCallback, updateCallback) if (opCallback) { RINOK(opCallback->ReportOperation(NEventIndexType::kInArcIndex, 0, NUpdateNotifyOp::kReplicate)) @@ -887,9 +1308,12 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt if (_stream) { - if (_phySize_Defined) - RINOK(updateCallback->SetTotal(_stat.PhySize)); - RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL)); + const CXzStatInfo *stat = GetStat(); + if (stat) + { + RINOK(updateCallback->SetTotal(stat->InSize)) + } + RINOK(InStream_SeekToBegin(_stream)) } CLocalProgress *lps = new CLocalProgress; @@ -901,20 +1325,80 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt COM_TRY_END } -STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps) +#endif + + +HRESULT CHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value) +{ + UString name = nameSpec; + name.MakeLower_Ascii(); + if (name.IsEmpty()) + return E_INVALIDARG; + + #ifndef Z7_EXTRACT_ONLY + + if (name[0] == L's') + { + const wchar_t *s = name.Ptr(1); + if (*s == 0) + { + bool useStr = false; + bool isSolid; + switch (value.vt) + { + case VT_EMPTY: isSolid = true; break; + case VT_BOOL: isSolid = (value.boolVal != VARIANT_FALSE); break; + case VT_BSTR: + if (!StringToBool(value.bstrVal, isSolid)) + useStr = true; + break; + default: return E_INVALIDARG; + } + if (!useStr) + { + _numSolidBytes = (isSolid ? XZ_PROPS_BLOCK_SIZE_SOLID : XZ_PROPS_BLOCK_SIZE_AUTO); + return S_OK; + } + } + return ParseSizeString(s, value, + 0, // percentsBase + _numSolidBytes) ? S_OK: E_INVALIDARG; + } + + return CMultiMethodProps::SetProperty(name, value); + + #else + + { + HRESULT hres; + if (SetCommonProperty(name, value, hres)) + return hres; + } + + return E_INVALIDARG; + + #endif +} + + + +Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)) { COM_TRY_BEGIN Init(); + for (UInt32 i = 0; i < numProps; i++) { - RINOK(SetProperty(names[i], values[i])); + RINOK(SetProperty(names[i], values[i])) } + #ifndef Z7_EXTRACT_ONLY + if (!_filterMethod.MethodName.IsEmpty()) { unsigned k; - for (k = 0; k < ARRAY_SIZE(g_NamePairs); k++) + for (k = 0; k < Z7_ARRAY_SIZE(g_NamePairs); k++) { const CMethodNamePair &pair = g_NamePairs[k]; if (StringsAreEqualNoCase_Ascii(_filterMethod.MethodName, pair.Name)) @@ -923,7 +1407,7 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR break; } } - if (k == ARRAY_SIZE(g_NamePairs)) + if (k == Z7_ARRAY_SIZE(g_NamePairs)) return E_INVALIDARG; } @@ -935,22 +1419,25 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR AString &methodName = _methods[0].MethodName; if (methodName.IsEmpty()) methodName = k_LZMA2_Name; - else if (!methodName.IsEqualTo_Ascii_NoCase(k_LZMA2_Name)) + else if ( + !methodName.IsEqualTo_Ascii_NoCase(k_LZMA2_Name) + && !methodName.IsEqualTo_Ascii_NoCase("xz")) return E_INVALIDARG; } + #endif + return S_OK; COM_TRY_END } -#endif REGISTER_ARC_IO( "xz", "xz txz", "* .tar", 0xC, - XZ_SIG, - 0, - NArcInfoFlags::kKeepName, - NULL) + XZ_SIG, 0 + , NArcInfoFlags::kKeepName + , 0 + , NULL) }} diff --git a/3rdparty/lzma/CPP/7zip/Archive/XzHandler.h b/3rdparty/lzma/CPP/7zip/Archive/XzHandler.h index 4a59e356a85..4d099548936 100644 --- a/3rdparty/lzma/CPP/7zip/Archive/XzHandler.h +++ b/3rdparty/lzma/CPP/7zip/Archive/XzHandler.h @@ -1,65 +1,11 @@ // XzHandler.h -#ifndef __XZ_HANDLER_H -#define __XZ_HANDLER_H - -#include "../../../C/Xz.h" - -#include "../ICoder.h" +#ifndef ZIP7_INC_XZ_HANDLER_H +#define ZIP7_INC_XZ_HANDLER_H namespace NArchive { namespace NXz { -struct CXzUnpackerCPP -{ - Byte *InBuf; - Byte *OutBuf; - CXzUnpacker p; - - CXzUnpackerCPP(); - ~CXzUnpackerCPP(); -}; - -struct CStatInfo -{ - UInt64 InSize; - UInt64 OutSize; - UInt64 PhySize; - - UInt64 NumStreams; - UInt64 NumBlocks; - - bool UnpackSize_Defined; - - bool NumStreams_Defined; - bool NumBlocks_Defined; - - bool IsArc; - bool UnexpectedEnd; - bool DataAfterEnd; - bool Unsupported; - bool HeadersError; - bool DataError; - bool CrcError; - - CStatInfo() { Clear(); } - - void Clear(); -}; - -struct CDecoder: public CStatInfo -{ - CXzUnpackerCPP xzu; - SRes DecodeRes; // it's not HRESULT - - CDecoder(): DecodeRes(SZ_OK) {} - - /* Decode() can return ERROR code only if there is progress or stream error. - Decode() returns S_OK in case of xz decoding error, but DecodeRes and CStatInfo contain error information */ - HRESULT Decode(ISequentialInStream *seqInStream, ISequentialOutStream *outStream, ICompressProgressInfo *compressProgress); - Int32 Get_Extract_OperationResult() const; -}; - }} #endif diff --git a/3rdparty/lzma/CPP/7zip/Asm.mak b/3rdparty/lzma/CPP/7zip/Asm.mak index 4f77dddfad0..c4073e89090 100644 --- a/3rdparty/lzma/CPP/7zip/Asm.mak +++ b/3rdparty/lzma/CPP/7zip/Asm.mak @@ -2,7 +2,7 @@ !IF "$(CPU)" == "ARM" $(ASM_OBJS): ../../../../Asm/Arm/$(*B).asm $(COMPL_ASM) -!ELSEIF "$(CPU)" != "IA64" && "$(CPU)" != "MIPS" +!ELSEIF "$(CPU)" != "IA64" && "$(CPU)" != "MIPS" && "$(CPU)" != "ARM64" $(ASM_OBJS): ../../../../Asm/x86/$(*B).asm $(COMPL_ASM) !ENDIF diff --git a/3rdparty/lzma/CPP/7zip/Bundles/Alone7z/Alone.dsp b/3rdparty/lzma/CPP/7zip/Bundles/Alone7z/Alone.dsp index d220b198b37..ef4ec6055b0 100644 --- a/3rdparty/lzma/CPP/7zip/Bundles/Alone7z/Alone.dsp +++ b/3rdparty/lzma/CPP/7zip/Bundles/Alone7z/Alone.dsp @@ -44,7 +44,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /Gr /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /FAc /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gr /MT /W4 /WX /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "Z7_LARGE_PAGES" /D "Z7_DEVICE_FILE" /FAcs /Yu"StdAfx.h" /FD /c # ADD BASE RSC /l 0x419 /d "NDEBUG" # ADD RSC /l 0x419 /d "NDEBUG" BSC32=bscmake.exe @@ -69,7 +69,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /Gr /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gr /MDd /W4 /WX /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "Z7_LARGE_PAGES" /D "Z7_DEVICE_FILE" /Yu"StdAfx.h" /FD /GZ /c # ADD BASE RSC /l 0x419 /d "_DEBUG" # ADD RSC /l 0x419 /d "_DEBUG" BSC32=bscmake.exe @@ -93,8 +93,8 @@ LINK32=link.exe # PROP Intermediate_Dir "ReleaseU" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" -# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /Yu"StdAfx.h" /FD /c -# ADD CPP /nologo /Gr /MD /W4 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_CONSOLE" /Yu"StdAfx.h" /FD /c +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gr /MD /W4 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_CONSOLE" /D "Z7_LARGE_PAGES" /D "Z7_DEVICE_FILE" /Yu"StdAfx.h" /FD /c # ADD BASE RSC /l 0x419 /d "NDEBUG" # ADD RSC /l 0x419 /d "NDEBUG" BSC32=bscmake.exe @@ -120,8 +120,8 @@ LINK32=link.exe # PROP Intermediate_Dir "DebugU" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c -# ADD CPP /nologo /Gr /MDd /W4 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gr /MDd /W4 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "Z7_LARGE_PAGES" /D "Z7_DEVICE_FILE" /Yu"StdAfx.h" /FD /GZ /c # ADD BASE RSC /l 0x419 /d "_DEBUG" # ADD RSC /l 0x419 /d "_DEBUG" BSC32=bscmake.exe @@ -144,10 +144,6 @@ LINK32=link.exe # PROP Default_Filter "" # Begin Source File -SOURCE=..\..\UI\Console\ArError.h -# End Source File -# Begin Source File - SOURCE=..\..\UI\Console\BenchCon.cpp # End Source File # Begin Source File @@ -270,6 +266,10 @@ SOURCE=..\..\..\Common\CommandLineParser.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\Common.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\ComTry.h # End Source File # Begin Source File @@ -290,6 +290,14 @@ SOURCE=..\..\..\Common\DynamicBuffer.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\DynLimBuf.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\DynLimBuf.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\IntToString.cpp # End Source File # Begin Source File @@ -306,6 +314,18 @@ SOURCE=..\..\..\Common\ListFileUtils.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\LzFindPrepare.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyBuffer2.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\MyCom.h # End Source File # Begin Source File @@ -330,6 +350,10 @@ SOURCE=..\..\..\Common\MyString.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\MyTypes.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\MyUnknown.h # End Source File # Begin Source File @@ -342,6 +366,14 @@ SOURCE=..\..\..\Common\MyVector.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\MyWindows.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyWindows.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\NewHandler.cpp # End Source File # Begin Source File @@ -350,6 +382,10 @@ SOURCE=..\..\..\Common\NewHandler.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\Sha256Prepare.cpp +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\Sha256Reg.cpp # End Source File # Begin Source File @@ -406,6 +442,10 @@ SOURCE=..\..\..\Common\Wildcard.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\XzCrc64Init.cpp +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\XzCrc64Reg.cpp # End Source File # End Group @@ -478,6 +518,14 @@ SOURCE=..\..\..\Windows\FileName.h # End Source File # Begin Source File +SOURCE=..\..\..\Windows\FileSystem.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileSystem.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Windows\Handle.h # End Source File # Begin Source File @@ -490,6 +538,10 @@ SOURCE=..\..\..\Windows\MemoryLock.h # End Source File # Begin Source File +SOURCE=..\..\..\Windows\NtCheck.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Windows\PropVariant.cpp # End Source File # Begin Source File @@ -506,7 +558,11 @@ SOURCE=..\..\..\Windows\PropVariantConv.h # End Source File # Begin Source File -SOURCE=..\..\..\Windows\Synchronization.cpp +SOURCE=..\..\..\Windows\Registry.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Registry.h # End Source File # Begin Source File @@ -522,6 +578,14 @@ SOURCE=..\..\..\Windows\System.h # End Source File # Begin Source File +SOURCE=..\..\..\Windows\SystemInfo.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\SystemInfo.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Windows\Thread.h # End Source File # Begin Source File @@ -626,6 +690,14 @@ SOURCE=..\..\Common\MethodProps.h # End Source File # Begin Source File +SOURCE=..\..\Common\MultiOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MultiOutStream.h +# End Source File +# Begin Source File + SOURCE=..\..\Common\OffsetStream.cpp # End Source File # Begin Source File @@ -746,10 +818,6 @@ SOURCE=..\..\Compress\ByteSwap.cpp # End Source File # Begin Source File -SOURCE=..\..\Compress\ByteSwap.h -# End Source File -# Begin Source File - SOURCE=..\..\Compress\CopyCoder.cpp # End Source File # Begin Source File @@ -804,6 +872,22 @@ SOURCE=..\..\Compress\LzmaEncoder.h SOURCE=..\..\Compress\LzmaRegister.cpp # End Source File +# Begin Source File + +SOURCE=..\..\Compress\XzDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\XzDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\XzEncoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\XzEncoder.h +# End Source File # End Group # Begin Group "Archive" @@ -1054,6 +1138,10 @@ SOURCE=..\..\UI\Common\EnumDirItems.h # End Source File # Begin Source File +SOURCE=..\..\UI\Common\ExitCode.h +# End Source File +# Begin Source File + SOURCE=..\..\UI\Common\Extract.cpp # End Source File # Begin Source File @@ -1178,7 +1266,7 @@ SOURCE=..\..\ICoder.h # End Source File # Begin Source File -SOURCE=..\..\IMyUnknown.h +SOURCE=..\..\IDecl.h # End Source File # Begin Source File @@ -1205,34 +1293,6 @@ SOURCE=..\..\PropID.h # PROP Default_Filter "" # Begin Source File -SOURCE=..\..\..\..\C\Sha256.c - -!IF "$(CFG)" == "Alone - Win32 Release" - -# ADD CPP /O2 -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "Alone - Win32 Debug" - -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" - -# SUBTRACT CPP /YX /Yc /Yu - -!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" - -# SUBTRACT CPP /YX /Yc /Yu - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\C\Sha256.h -# End Source File -# Begin Source File - SOURCE=..\..\..\..\C\Xz.c !IF "$(CFG)" == "Alone - Win32 Release" @@ -1429,6 +1489,14 @@ SOURCE=..\..\..\..\C\7zStream.c # End Source File # Begin Source File +SOURCE=..\..\..\..\C\7zTypes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zWindows.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\Aes.c !IF "$(CFG)" == "Alone - Win32 Release" @@ -1561,6 +1629,10 @@ SOURCE=..\..\..\..\C\BraIA64.c # End Source File # Begin Source File +SOURCE=..\..\..\..\C\Compiler.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\CpuArch.c !IF "$(CFG)" == "Alone - Win32 Release" @@ -1618,6 +1690,15 @@ SOURCE=..\..\..\..\C\Delta.h # End Source File # Begin Source File +SOURCE=..\..\..\..\C\DllSecur.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\DllSecur.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\IStream.h # End Source File # Begin Source File @@ -1640,6 +1721,30 @@ SOURCE=..\..\..\..\C\LzFindMt.h # End Source File # Begin Source File +SOURCE=..\..\..\..\C\LzFindOpt.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\Compress\Lz\LzHash.h # End Source File # Begin Source File @@ -1676,6 +1781,34 @@ SOURCE=..\..\..\..\C\Lzma2Dec.h # End Source File # Begin Source File +SOURCE=..\..\..\..\C\Lzma2DecMt.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2DecMt.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\Lzma2Enc.c !IF "$(CFG)" == "Alone - Win32 Release" @@ -1769,16 +1902,105 @@ SOURCE=..\..\..\..\C\MtCoder.h # End Source File # Begin Source File -SOURCE=..\..\..\..\C\Threads.c +SOURCE=..\..\..\..\C\MtDec.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + # SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + # End Source File # Begin Source File -SOURCE=..\..\..\..\C\Threads.h +SOURCE=..\..\..\..\C\MtDec.h # End Source File # Begin Source File -SOURCE=..\..\..\..\C\Types.h +SOURCE=..\..\..\..\C\RotateDefs.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sha256.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sha256.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sha256Opt.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\SwapBytes.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\SwapBytes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.h # End Source File # End Group # Begin Group "Crypto" @@ -1806,6 +2028,10 @@ SOURCE=..\..\Crypto\MyAes.h # End Source File # Begin Source File +SOURCE=..\..\Crypto\MyAesReg.cpp +# End Source File +# Begin Source File + SOURCE=..\..\Crypto\RandGen.cpp # End Source File # Begin Source File diff --git a/3rdparty/lzma/CPP/7zip/Bundles/Alone7z/StdAfx.h b/3rdparty/lzma/CPP/7zip/Bundles/Alone7z/StdAfx.h index 2854ff3e935..035267ccd02 100644 --- a/3rdparty/lzma/CPP/7zip/Bundles/Alone7z/StdAfx.h +++ b/3rdparty/lzma/CPP/7zip/Bundles/Alone7z/StdAfx.h @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../../Common/Common.h" #endif diff --git a/3rdparty/lzma/CPP/7zip/Bundles/Alone7z/makefile b/3rdparty/lzma/CPP/7zip/Bundles/Alone7z/makefile index 15c51f91987..1f857c541ad 100644 --- a/3rdparty/lzma/CPP/7zip/Bundles/Alone7z/makefile +++ b/3rdparty/lzma/CPP/7zip/Bundles/Alone7z/makefile @@ -1,17 +1,18 @@ PROG = 7zr.exe -MY_CONSOLE = 1 -CFLAGS = $(CFLAGS) -DPROG_VARIANT_R -!IFNDEF UNDER_CE -CFLAGS = $(CFLAGS) -DWIN_LONG_PATH -!ENDIF +# USE_C_AES = 1 +# USE_C_SHA = 1 + +CFLAGS = $(CFLAGS) -DZ7_PROG_VARIANT_R COMMON_OBJS = \ $O\CommandLineParser.obj \ $O\CRC.obj \ $O\CrcReg.obj \ + $O\DynLimBuf.obj \ $O\IntToString.obj \ $O\ListFileUtils.obj \ + $O\LzFindPrepare.obj \ $O\NewHandler.obj \ $O\StdInStream.obj \ $O\StdOutStream.obj \ @@ -22,6 +23,7 @@ COMMON_OBJS = \ $O\UTFConvert.obj \ $O\MyVector.obj \ $O\Wildcard.obj \ + $O\XzCrc64Init.obj \ $O\XzCrc64Reg.obj \ WIN_OBJS = \ @@ -32,11 +34,13 @@ WIN_OBJS = \ $O\FileIO.obj \ $O\FileLink.obj \ $O\FileName.obj \ + $O\FileSystem.obj \ $O\MemoryLock.obj \ $O\PropVariant.obj \ $O\PropVariantConv.obj \ - $O\Synchronization.obj \ + $O\Registry.obj \ $O\System.obj \ + $O\SystemInfo.obj \ $O\TimeUtils.obj \ 7ZIP_COMMON_OBJS = \ @@ -50,6 +54,7 @@ WIN_OBJS = \ $O\LimitedStreams.obj \ $O\MethodId.obj \ $O\MethodProps.obj \ + $O\MultiOutStream.obj \ $O\OffsetStream.obj \ $O\OutBuffer.obj \ $O\ProgressUtils.obj \ @@ -109,6 +114,8 @@ COMPRESS_OBJS = \ $O\LzmaDecoder.obj \ $O\LzmaEncoder.obj \ $O\LzmaRegister.obj \ + $O\XzDecoder.obj \ + $O\XzEncoder.obj \ CRYPTO_OBJS = \ $O\7zAes.obj \ @@ -130,12 +137,14 @@ C_OBJS = \ $O\LzFind.obj \ $O\LzFindMt.obj \ $O\Lzma2Dec.obj \ + $O\Lzma2DecMt.obj \ $O\Lzma2Enc.obj \ $O\LzmaDec.obj \ $O\LzmaEnc.obj \ $O\MtCoder.obj \ - $O\Sha256.obj \ + $O\MtDec.obj \ $O\Sort.obj \ + $O\SwapBytes.obj \ $O\Threads.obj \ $O\Xz.obj \ $O\XzDec.obj \ @@ -147,5 +156,8 @@ C_OBJS = \ !include "../../Aes.mak" !include "../../Crc.mak" !include "../../Crc64.mak" +!include "../../LzFindOpt.mak" +!include "../../LzmaDec.mak" +!include "../../Sha256.mak" !include "../../7zip.mak" diff --git a/3rdparty/lzma/CPP/7zip/Bundles/Alone7z/makefile.gcc b/3rdparty/lzma/CPP/7zip/Bundles/Alone7z/makefile.gcc new file mode 100644 index 00000000000..6d92c19bfbd --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/Bundles/Alone7z/makefile.gcc @@ -0,0 +1,276 @@ +PROG = 7zr + +CONSOLE_VARIANT_FLAGS=-DZ7_PROG_VARIANT_R + +# IS_X64 = 1 +# USE_ASM = 1 +# ST_MODE = 1 + +ifdef SystemDrive +IS_MINGW = 1 +else +ifdef SYSTEMDRIVE +# ifdef OS +IS_MINGW = 1 +endif +endif + +include ../../LzmaDec_gcc.mak + + +LOCAL_FLAGS_ST = +MT_OBJS = + + +ifdef ST_MODE + +LOCAL_FLAGS_ST = -DZ7_ST + +ifdef IS_MINGW +MT_OBJS = \ + $O/Threads.o \ + +endif + +else + +MT_OBJS = \ + $O/LzFindMt.o \ + $O/LzFindOpt.o \ + $O/StreamBinder.o \ + $O/VirtThread.o \ + $O/Threads.o \ + + + +endif + + + +LOCAL_FLAGS_SYS = + +ifdef IS_MINGW + +LOCAL_FLAGS_SYS = \ + -DZ7_LARGE_PAGES \ + -DZ7_LONG_PATH \ + -DZ7_DEVICE_FILE \ + +SYS_OBJS = \ + $O/FileSystem.o \ + $O/Registry.o \ + $O/MemoryLock.o \ + $O/DLL.o \ + $O/DllSecur.o \ + $O/resource.o \ + +else + +SYS_OBJS = \ + $O/MyWindows.o \ + +endif + +LOCAL_FLAGS = \ + $(LOCAL_FLAGS_ST) \ + $(LOCAL_FLAGS_SYS) \ + + +CONSOLE_OBJS = \ + $O/BenchCon.o \ + $O/ConsoleClose.o \ + $O/DynLimBuf.o \ + $O/ExtractCallbackConsole.o \ + $O/HashCon.o \ + $O/List.o \ + $O/Main.o \ + $O/MainAr.o \ + $O/OpenCallbackConsole.o \ + $O/PercentPrinter.o \ + $O/UpdateCallbackConsole.o \ + $O/UserInputUtils.o \ + +UI_COMMON_OBJS = \ + $O/ArchiveCommandLine.o \ + $O/ArchiveExtractCallback.o \ + $O/ArchiveOpenCallback.o \ + $O/Bench.o \ + $O/DefaultName.o \ + $O/EnumDirItems.o \ + $O/Extract.o \ + $O/ExtractingFilePath.o \ + $O/HashCalc.o \ + $O/LoadCodecs.o \ + $O/OpenArchive.o \ + $O/PropIDUtils.o \ + $O/SetProperties.o \ + $O/SortUtils.o \ + $O/TempFiles.o \ + $O/Update.o \ + $O/UpdateAction.o \ + $O/UpdateCallback.o \ + $O/UpdatePair.o \ + $O/UpdateProduce.o \ + +COMMON_OBJS = \ + $O/CommandLineParser.o \ + $O/CRC.o \ + $O/CrcReg.o \ + $O/IntToString.o \ + $O/ListFileUtils.o \ + $O/LzFindPrepare.o \ + $O/MyString.o \ + $O/MyVector.o \ + $O/NewHandler.o \ + $O/Sha256Prepare.o \ + $O/Sha256Reg.o \ + $O/StringConvert.o \ + $O/StringToInt.o \ + $O/StdInStream.o \ + $O/StdOutStream.o \ + $O/UTFConvert.o \ + $O/Wildcard.o \ + $O/XzCrc64Init.o \ + $O/XzCrc64Reg.o \ + +WIN_OBJS = \ + $O/ErrorMsg.o \ + $O/FileDir.o \ + $O/FileFind.o \ + $O/FileIO.o \ + $O/FileLink.o \ + $O/FileName.o \ + $O/PropVariant.o \ + $O/PropVariantConv.o \ + $O/System.o \ + $O/SystemInfo.o \ + $O/TimeUtils.o \ + +7ZIP_COMMON_OBJS = \ + $O/CreateCoder.o \ + $O/CWrappers.o \ + $O/FilePathAutoRename.o \ + $O/FileStreams.o \ + $O/InBuffer.o \ + $O/InOutTempBuffer.o \ + $O/FilterCoder.o \ + $O/LimitedStreams.o \ + $O/MethodId.o \ + $O/MethodProps.o \ + $O/MultiOutStream.o \ + $O/OffsetStream.o \ + $O/OutBuffer.o \ + $O/ProgressUtils.o \ + $O/PropId.o \ + $O/StreamObjects.o \ + $O/StreamUtils.o \ + $O/UniqBlocks.o \ + +AR_OBJS = \ + $O/LzmaHandler.o \ + $O/SplitHandler.o \ + $O/XzHandler.o \ + +AR_COMMON_OBJS = \ + $O/CoderMixer2.o \ + $O/DummyOutStream.o \ + $O/HandlerOut.o \ + $O/InStreamWithCRC.o \ + $O/ItemNameUtils.o \ + $O/MultiStream.o \ + $O/OutStreamWithCRC.o \ + $O/ParseProperties.o \ + +7Z_OBJS = \ + $O/7zCompressionMode.o \ + $O/7zDecode.o \ + $O/7zEncode.o \ + $O/7zExtract.o \ + $O/7zFolderInStream.o \ + $O/7zHandler.o \ + $O/7zHandlerOut.o \ + $O/7zHeader.o \ + $O/7zIn.o \ + $O/7zOut.o \ + $O/7zProperties.o \ + $O/7zRegister.o \ + $O/7zSpecStream.o \ + $O/7zUpdate.o \ + +COMPRESS_OBJS = \ + $O/Bcj2Coder.o \ + $O/Bcj2Register.o \ + $O/BcjCoder.o \ + $O/BcjRegister.o \ + $O/BranchMisc.o \ + $O/BranchRegister.o \ + $O/ByteSwap.o \ + $O/CopyCoder.o \ + $O/CopyRegister.o \ + $O/DeltaFilter.o \ + $O/Lzma2Decoder.o \ + $O/Lzma2Encoder.o \ + $O/Lzma2Register.o \ + $O/LzmaDecoder.o \ + $O/LzmaEncoder.o \ + $O/LzmaRegister.o \ + $O/XzDecoder.o \ + $O/XzEncoder.o \ + +CRYPTO_OBJS = \ + $O/7zAes.o \ + $O/7zAesRegister.o \ + $O/MyAes.o \ + $O/MyAesReg.o \ + $O/RandGen.o \ + +C_OBJS = \ + $O/7zStream.o \ + $O/Alloc.o \ + $O/Bcj2.o \ + $O/Bcj2Enc.o \ + $O/Bra.o \ + $O/Bra86.o \ + $O/BraIA64.o \ + $O/CpuArch.o \ + $O/Delta.o \ + $O/LzFind.o \ + $O/Lzma2Dec.o \ + $O/Lzma2DecMt.o \ + $O/Lzma2Enc.o \ + $O/LzmaDec.o \ + $O/LzmaEnc.o \ + $O/MtCoder.o \ + $O/MtDec.o \ + $O/Sha256.o \ + $O/Sha256Opt.o \ + $O/SwapBytes.o \ + $O/Xz.o \ + $O/XzDec.o \ + $O/XzEnc.o \ + $O/XzIn.o \ + $O/XzCrc64.o \ + $O/XzCrc64Opt.o \ + $O/7zCrc.o \ + $O/7zCrcOpt.o \ + $O/Aes.o \ + $O/AesOpt.o \ + + +OBJS = \ + $(LZMA_DEC_OPT_OBJS) \ + $(C_OBJS) \ + $(MT_OBJS) \ + $(SYS_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(COMPRESS_OBJS) \ + $(CRYPTO_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(AR_OBJS) \ + $(AR_COMMON_OBJS) \ + $(7Z_OBJS) \ + $(UI_COMMON_OBJS) \ + $(CONSOLE_OBJS) \ + +include ../../7zip_gcc.mak diff --git a/3rdparty/lzma/CPP/7zip/Bundles/Alone7z/resource.rc b/3rdparty/lzma/CPP/7zip/Bundles/Alone7z/resource.rc index b3fb079a630..593785007a0 100644 --- a/3rdparty/lzma/CPP/7zip/Bundles/Alone7z/resource.rc +++ b/3rdparty/lzma/CPP/7zip/Bundles/Alone7z/resource.rc @@ -1,3 +1,7 @@ #include "../../../../C/7zVersion.rc" MY_VERSION_INFO_APP("7-Zip Reduced Standalone Console", "7zr") + +#ifndef UNDER_CE +1 24 MOVEABLE PURE "../../UI/Console/Console.manifest" +#endif diff --git a/3rdparty/lzma/CPP/7zip/Bundles/Format7zExtractR/StdAfx.h b/3rdparty/lzma/CPP/7zip/Bundles/Format7zExtractR/StdAfx.h index 2854ff3e935..035267ccd02 100644 --- a/3rdparty/lzma/CPP/7zip/Bundles/Format7zExtractR/StdAfx.h +++ b/3rdparty/lzma/CPP/7zip/Bundles/Format7zExtractR/StdAfx.h @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../../Common/Common.h" #endif diff --git a/3rdparty/lzma/CPP/7zip/Bundles/Format7zExtractR/makefile b/3rdparty/lzma/CPP/7zip/Bundles/Format7zExtractR/makefile index 724477e9493..50b84d879a2 100644 --- a/3rdparty/lzma/CPP/7zip/Bundles/Format7zExtractR/makefile +++ b/3rdparty/lzma/CPP/7zip/Bundles/Format7zExtractR/makefile @@ -1,8 +1,8 @@ PROG = 7zxr.dll DEF_FILE = ../../Archive/Archive2.def CFLAGS = $(CFLAGS) \ - -DEXTRACT_ONLY \ - -D_NO_CRYPTO + -DZ7_EXTRACT_ONLY \ + -DZ7_NO_CRYPTO COMMON_OBJS = \ $O\CRC.obj \ @@ -77,6 +77,7 @@ COMPRESS_OBJS = \ $O\LzmaRegister.obj \ C_OBJS = \ + $O\7zStream.obj \ $O\Alloc.obj \ $O\Bcj2.obj \ $O\Bra.obj \ @@ -85,9 +86,13 @@ C_OBJS = \ $O\CpuArch.obj \ $O\Delta.obj \ $O\Lzma2Dec.obj \ + $O\Lzma2DecMt.obj \ $O\LzmaDec.obj \ + $O\MtDec.obj \ + $O\SwapBytes.obj \ $O\Threads.obj \ !include "../../Crc.mak" +!include "../../LzmaDec.mak" !include "../../7zip.mak" diff --git a/3rdparty/lzma/CPP/7zip/Bundles/Format7zR/StdAfx.h b/3rdparty/lzma/CPP/7zip/Bundles/Format7zR/StdAfx.h index 2854ff3e935..035267ccd02 100644 --- a/3rdparty/lzma/CPP/7zip/Bundles/Format7zR/StdAfx.h +++ b/3rdparty/lzma/CPP/7zip/Bundles/Format7zR/StdAfx.h @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../../Common/Common.h" #endif diff --git a/3rdparty/lzma/CPP/7zip/Bundles/Format7zR/makefile b/3rdparty/lzma/CPP/7zip/Bundles/Format7zR/makefile index 916dc568c38..24497550475 100644 --- a/3rdparty/lzma/CPP/7zip/Bundles/Format7zR/makefile +++ b/3rdparty/lzma/CPP/7zip/Bundles/Format7zR/makefile @@ -1,12 +1,13 @@ PROG = 7zra.dll DEF_FILE = ../../Archive/Archive2.def CFLAGS = $(CFLAGS) \ - -D_NO_CRYPTO + -DZ7_NO_CRYPTO COMMON_OBJS = \ $O\CRC.obj \ $O\CrcReg.obj \ $O\IntToString.obj \ + $O\LzFindPrepare.obj \ $O\NewHandler.obj \ $O\MyString.obj \ $O\StringConvert.obj \ @@ -91,6 +92,7 @@ COMPRESS_OBJS = \ $O\LzmaRegister.obj \ C_OBJS = \ + $O\7zStream.obj \ $O\Alloc.obj \ $O\Bcj2.obj \ $O\Bcj2Enc.obj \ @@ -102,12 +104,17 @@ C_OBJS = \ $O\LzFind.obj \ $O\LzFindMt.obj \ $O\Lzma2Dec.obj \ + $O\Lzma2DecMt.obj \ $O\Lzma2Enc.obj \ $O\LzmaDec.obj \ $O\LzmaEnc.obj \ $O\MtCoder.obj \ + $O\MtDec.obj \ + $O\SwapBytes.obj \ $O\Threads.obj \ !include "../../Crc.mak" +!include "../../LzFindOpt.mak" +!include "../../LzmaDec.mak" !include "../../7zip.mak" diff --git a/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp b/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp index 178753e5373..ac1334f4358 100644 --- a/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp +++ b/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp @@ -1,8 +1,8 @@ -// LzmaAlone.cpp + // LzmaAlone.cpp #include "StdAfx.h" -#include <stdio.h> +// #include <stdio.h> #if (defined(_WIN32) || defined(OS2) || defined(MSDOS)) && !defined(UNDER_CE) #include <fcntl.h> @@ -12,16 +12,17 @@ #define MY_SET_BINARY_MODE(file) #endif -#include "../../../Common/MyWindows.h" -#include "../../../Common/MyInitGuid.h" - +#include "../../../../C/CpuArch.h" #include "../../../../C/7zVersion.h" #include "../../../../C/Alloc.h" #include "../../../../C/Lzma86.h" +#include "../../../Common/MyWindows.h" +#include "../../../Common/MyInitGuid.h" + #include "../../../Windows/NtCheck.h" -#ifndef _7ZIP_ST +#ifndef Z7_ST #include "../../../Windows/System.h" #endif @@ -39,14 +40,18 @@ #include "../../UI/Console/BenchCon.h" #include "../../UI/Console/ConsoleClose.h" +extern +bool g_LargePagesMode; +bool g_LargePagesMode = false; + using namespace NCommandLineParser; static const unsigned kDictSizeLog = 24; -static const char *kCopyrightString = "\nLZMA " MY_VERSION_COPYRIGHT_DATE "\n\n"; +#define kCopyrightString "\nLZMA " MY_VERSION_CPU " : " MY_COPYRIGHT_DATE "\n\n" -static const char *kHelpString = - "Usage: LZMA <command> [inputFile] [outputFile] [<switches>...]\n" +static const char * const kHelpString = + "Usage: lzma <command> [inputFile] [outputFile] [<switches>...]\n" "\n" "<command>\n" " e : Encode file\n" @@ -67,9 +72,9 @@ static const char *kHelpString = " -so : write data to stdout\n"; -static const char *kCantAllocate = "Can not allocate memory"; -static const char *kReadError = "Read error"; -static const char *kWriteError = "Write error"; +static const char * const kCantAllocate = "Cannot allocate memory"; +static const char * const kReadError = "Read error"; +static const char * const kWriteError = "Write error"; namespace NKey { @@ -95,28 +100,51 @@ enum Enum }; } +#define SWFRM_3(t, mu, mi) t, mu, mi, NULL + +#define SWFRM_1(t) SWFRM_3(t, false, 0) +#define SWFRM_SIMPLE SWFRM_1(NSwitchType::kSimple) +#define SWFRM_STRING SWFRM_1(NSwitchType::kString) + +#define SWFRM_STRING_SINGL(mi) SWFRM_3(NSwitchType::kString, false, mi) + static const CSwitchForm kSwitchForms[] = { - { "?", NSwitchType::kSimple, false }, - { "H", NSwitchType::kSimple, false }, - { "MM", NSwitchType::kString, false, 1 }, - { "X", NSwitchType::kString, false, 1 }, - { "A", NSwitchType::kString, false, 1 }, - { "D", NSwitchType::kString, false, 1 }, - { "FB", NSwitchType::kString, false, 1 }, - { "MC", NSwitchType::kString, false, 1 }, - { "LC", NSwitchType::kString, false, 1 }, - { "LP", NSwitchType::kString, false, 1 }, - { "PB", NSwitchType::kString, false, 1 }, - { "MF", NSwitchType::kString, false, 1 }, - { "MT", NSwitchType::kString, false, 0 }, - { "EOS", NSwitchType::kSimple, false }, - { "SI", NSwitchType::kSimple, false }, - { "SO", NSwitchType::kSimple, false }, + { "?", SWFRM_SIMPLE }, + { "H", SWFRM_SIMPLE }, + { "MM", SWFRM_STRING_SINGL(1) }, + { "X", SWFRM_STRING_SINGL(1) }, + { "A", SWFRM_STRING_SINGL(1) }, + { "D", SWFRM_STRING_SINGL(1) }, + { "FB", SWFRM_STRING_SINGL(1) }, + { "MC", SWFRM_STRING_SINGL(1) }, + { "LC", SWFRM_STRING_SINGL(1) }, + { "LP", SWFRM_STRING_SINGL(1) }, + { "PB", SWFRM_STRING_SINGL(1) }, + { "MF", SWFRM_STRING_SINGL(1) }, + { "MT", SWFRM_STRING }, + { "EOS", SWFRM_SIMPLE }, + { "SI", SWFRM_SIMPLE }, + { "SO", SWFRM_SIMPLE }, { "F86", NSwitchType::kChar, false, 0, "+" } }; +static void Convert_UString_to_AString(const UString &s, AString &temp) +{ + int codePage = CP_OEMCP; + /* + int g_CodePage = -1; + int codePage = g_CodePage; + if (codePage == -1) + codePage = CP_OEMCP; + if (codePage == CP_UTF8) + ConvertUnicodeToUTF8(s, temp); + else + */ + UnicodeStringToMultiByte2(temp, s, (UINT)codePage); +} + static void PrintErr(const char *s) { fputs(s, stderr); @@ -135,10 +163,12 @@ static void PrintError(const char *s) PrintErr_LF(s); } -static void PrintError2(const char *s1, const wchar_t *s2) +static void PrintError2(const char *s1, const UString &s2) { PrintError(s1); - PrintErr_LF(GetOemString(s2)); + AString a; + Convert_UString_to_AString(s2, a); + PrintErr_LF(a); } static void PrintError_int(const char *s, int code) @@ -190,25 +220,22 @@ static void PrintHelp() Print(kHelpString); } -class CProgressPrint: - public ICompressProgressInfo, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_COM_1( + CProgressPrint, + ICompressProgressInfo +) UInt64 _size1; UInt64 _size2; public: CProgressPrint(): _size1(0), _size2(0) {} void ClosePrint(); - - MY_UNKNOWN_IMP1(ICompressProgressInfo) - - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); }; #define BACK_STR \ "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b" -static const char *kBackSpaces = +static const char * const kBackSpaces = BACK_STR " " BACK_STR; @@ -219,7 +246,7 @@ void CProgressPrint::ClosePrint() Print(kBackSpaces); } -STDMETHODIMP CProgressPrint::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) +Z7_COM7F_IMF(CProgressPrint::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)) { if (NConsoleClose::TestBreakSignal()) return E_ABORT; @@ -243,6 +270,7 @@ STDMETHODIMP CProgressPrint::SetRatioInfo(const UInt64 *inSize, const UInt64 *ou } +Z7_ATTR_NORETURN static void IncorrectCommand() { throw "Incorrect command"; @@ -286,19 +314,21 @@ static int Error_HRESULT(const char *s, HRESULT res) else { char temp[32]; - ConvertUInt32ToHex(res, temp); + ConvertUInt32ToHex((UInt32)res, temp); PrintErr("Error code = 0x"); PrintErr_LF(temp); } return 1; } +#if defined(_UNICODE) && !defined(_WIN64) && !defined(UNDER_CE) #define NT_CHECK_FAIL_ACTION PrintError("Unsupported Windows version"); return 1; +#endif static void AddProp(CObjectVector<CProperty> &props2, const char *name, const wchar_t *val) { CProperty &prop = props2.AddNew(); - prop.Name.SetFromAscii(name); + prop.Name = name; prop.Value = val; } @@ -322,10 +352,10 @@ static int main2(int numArgs, const char *args[]) for (int i = 1; i < numArgs; i++) commandStrings.Add(MultiByteToUnicodeString(args[i])); - CParser parser(ARRAY_SIZE(kSwitchForms)); + CParser parser; try { - if (!parser.ParseStrings(kSwitchForms, commandStrings)) + if (!parser.ParseStrings(kSwitchForms, Z7_ARRAY_SIZE(kSwitchForms), commandStrings)) { PrintError2(parser.ErrorMessage, parser.ErrorLine); return 1; @@ -376,13 +406,13 @@ static int main2(int numArgs, const char *args[]) AddProp(props2, "x", s); } - UString mf = L"BT4"; + UString mf ("BT4"); if (parser[NKey::kMatchFinder].ThereIs) mf = parser[NKey::kMatchFinder].PostStrings[0]; UInt32 numThreads = (UInt32)(Int32)-1; - #ifndef _7ZIP_ST + #ifndef Z7_ST if (parser[NKey::kMultiThread].ThereIs) { @@ -453,7 +483,7 @@ static int main2(int numArgs, const char *args[]) inStream = inStreamSpec; if (!inStreamSpec->Open(us2fs(inputName))) { - PrintError2("can not open input file", inputName); + PrintError2("Cannot open input file", inputName); return 1; } } @@ -473,7 +503,7 @@ static int main2(int numArgs, const char *args[]) outStream = outStreamSpec; if (!outStreamSpec->Create(us2fs(outputName), true)) { - PrintError2("can not open output file", outputName); + PrintError2("Cannot open output file", outputName); return 1; } } @@ -483,8 +513,8 @@ static int main2(int numArgs, const char *args[]) if (inStreamSpec) { - if (!inStreamSpec->File.GetLength(fileSize)) - throw "Can not get file length"; + if (!inStreamSpec->GetLength(fileSize)) + throw "Cannot get file length"; fileSizeDefined = true; if (!stdOutMode) Print_Size("Input size: ", fileSize); @@ -511,7 +541,7 @@ static int main2(int numArgs, const char *args[]) You can use xz format instead, if you want to use filters */ if (parser[NKey::kEOS].ThereIs || stdInMode) - throw "Can not use stdin in this mode"; + throw "Cannot use stdin in this mode"; size_t inSize = (size_t)fileSize; @@ -528,7 +558,7 @@ static int main2(int numArgs, const char *args[]) } if (ReadStream_FAIL(inStream, inBuffer, inSize) != S_OK) - throw "Can not read"; + throw "Cannot read"; Byte *outBuffer = NULL; size_t outSize; @@ -644,7 +674,7 @@ static int main2(int numArgs, const char *args[]) NCoderPropID::kMatchFinderCycles, }; - const unsigned kNumPropsMax = ARRAY_SIZE(propIDs); + const unsigned kNumPropsMax = Z7_ARRAY_SIZE(propIDs); PROPVARIANT props[kNumPropsMax]; for (int p = 0; p < 6; p++) @@ -725,7 +755,7 @@ static int main2(int numArgs, const char *args[]) throw "SetDecoderProperties error"; UInt64 unpackSize = 0; - for (int i = 0; i < 8; i++) + for (unsigned i = 0; i < 8; i++) unpackSize |= ((UInt64)header[kPropertiesSize + i]) << (8 * i); bool unpackSizeDefined = (unpackSize != (UInt64)(Int64)-1); @@ -760,7 +790,7 @@ static int main2(int numArgs, const char *args[]) return 0; } -int MY_CDECL main(int numArgs, const char *args[]) +int Z7_CDECL main(int numArgs, const char *args[]) { NConsoleClose::CCtrlHandlerSetter ctrlHandlerSetter; diff --git a/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsp b/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsp index f8267a11f24..5a8911b25c2 100644 --- a/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsp +++ b/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsp @@ -132,6 +132,10 @@ SOURCE=..\..\..\Windows\FileIO.h # End Source File # Begin Source File +SOURCE=..\..\..\Windows\NtCheck.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Windows\PropVariant.cpp # End Source File # Begin Source File @@ -140,11 +144,11 @@ SOURCE=..\..\..\Windows\PropVariant.h # End Source File # Begin Source File -SOURCE=..\..\..\Windows\Synchronization.cpp +SOURCE=..\..\..\Windows\Registry.cpp # End Source File # Begin Source File -SOURCE=..\..\..\Windows\Synchronization.h +SOURCE=..\..\..\Windows\Registry.h # End Source File # Begin Source File @@ -156,6 +160,14 @@ SOURCE=..\..\..\Windows\System.h # End Source File # Begin Source File +SOURCE=..\..\..\Windows\SystemInfo.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\SystemInfo.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Windows\Thread.h # End Source File # End Group @@ -172,6 +184,10 @@ SOURCE=..\..\..\Common\CommandLineParser.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\Common.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\ComTry.h # End Source File # Begin Source File @@ -196,10 +212,30 @@ SOURCE=..\..\..\Common\IntToString.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\LzFindPrepare.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyBuffer2.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\MyCom.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\MyInitGuid.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyLinux.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\MyString.cpp # End Source File # Begin Source File @@ -208,6 +244,10 @@ SOURCE=..\..\..\Common\MyString.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\MyTypes.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\MyUnknown.h # End Source File # Begin Source File @@ -254,6 +294,14 @@ SOURCE=..\..\..\Common\StringToInt.h SOURCE=..\..\..\Common\Types.h # End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.h +# End Source File # End Group # Begin Group "7zip Common" @@ -300,6 +348,14 @@ SOURCE=..\..\Common\MethodProps.h # End Source File # Begin Source File +SOURCE=..\..\Common\StreamObjects.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.h +# End Source File +# Begin Source File + SOURCE=..\..\Common\StreamUtils.cpp # End Source File # Begin Source File @@ -318,14 +374,6 @@ SOURCE=..\..\UI\Common\Bench.cpp SOURCE=..\..\UI\Common\Bench.h # End Source File -# Begin Source File - -SOURCE=..\..\UI\Common\LoadCodecs.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\UI\Common\LoadCodecs.h -# End Source File # End Group # Begin Group "Console" @@ -370,21 +418,16 @@ SOURCE=..\..\..\..\C\7zTypes.h # End Source File # Begin Source File -SOURCE=..\..\..\..\C\Alloc.c -# SUBTRACT CPP /YX /Yc /Yu +SOURCE=..\..\..\..\C\7zWindows.h # End Source File # Begin Source File -SOURCE=..\..\..\..\C\Alloc.h -# End Source File -# Begin Source File - -SOURCE=..\..\..\..\C\Bra.c +SOURCE=..\..\..\..\C\Alloc.c # SUBTRACT CPP /YX /Yc /Yu # End Source File # Begin Source File -SOURCE=..\..\..\..\C\Bra.h +SOURCE=..\..\..\..\C\Alloc.h # End Source File # Begin Source File @@ -393,8 +436,7 @@ SOURCE=..\..\..\..\C\Bra86.c # End Source File # Begin Source File -SOURCE=..\..\..\..\C\BraIA64.c -# SUBTRACT CPP /YX /Yc /Yu +SOURCE=..\..\..\..\C\Compiler.h # End Source File # Begin Source File @@ -425,6 +467,11 @@ SOURCE=..\..\..\..\C\LzFindMt.h # End Source File # Begin Source File +SOURCE=..\..\..\..\C\LzFindOpt.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\LzHash.h # End Source File # Begin Source File @@ -469,6 +516,22 @@ SOURCE=..\..\..\..\C\Threads.c SOURCE=..\..\..\..\C\Threads.h # End Source File # End Group +# Begin Group "7zip" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\ICoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\IDecl.h +# End Source File +# Begin Source File + +SOURCE=..\..\IProgress.h +# End Source File +# End Group # Begin Source File SOURCE=.\LzmaAlone.cpp diff --git a/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/StdAfx.h b/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/StdAfx.h index 2854ff3e935..035267ccd02 100644 --- a/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/StdAfx.h +++ b/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/StdAfx.h @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../../Common/Common.h" #endif diff --git a/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/makefile b/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/makefile index 54919f73374..f303c31fd10 100644 --- a/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/makefile +++ b/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/makefile @@ -1,6 +1,8 @@ PROG = lzma.exe MY_CONSOLE = 1 -CFLAGS = $(CFLAGS) + +# CFLAGS = $(CFLAGS) -DZ7_ST + CURRENT_OBJS = \ $O\LzmaAlone.obj \ @@ -15,24 +17,28 @@ COMMON_OBJS = \ $O\CRC.obj \ $O\CrcReg.obj \ $O\IntToString.obj \ + $O\LzFindPrepare.obj \ $O\MyString.obj \ + $O\MyVector.obj \ $O\NewHandler.obj \ $O\StringConvert.obj \ $O\StringToInt.obj \ - $O\MyVector.obj + $O\Wildcard.obj \ WIN_OBJS = \ $O\FileIO.obj \ $O\PropVariant.obj \ - $O\System.obj + $O\Registry.obj \ + $O\System.obj \ + $O\SystemInfo.obj \ 7ZIP_COMMON_OBJS = \ - $O\CWrappers.obj \ $O\CreateCoder.obj \ + $O\CWrappers.obj \ $O\FileStreams.obj \ $O\FilterCoder.obj \ $O\MethodProps.obj \ - $O\OutBuffer.obj \ + $O\StreamObjects.obj \ $O\StreamUtils.obj \ UI_COMMON_OBJS = \ @@ -55,5 +61,7 @@ C_OBJS = \ $O\Threads.obj \ !include "../../Crc.mak" +!include "../../LzFindOpt.mak" +!include "../../LzmaDec.mak" !include "../../7zip.mak" diff --git a/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/makefile.gcc b/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/makefile.gcc index 97fe450841f..dd19a0e6a56 100644 --- a/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/makefile.gcc +++ b/3rdparty/lzma/CPP/7zip/Bundles/LzmaCon/makefile.gcc @@ -1,195 +1,126 @@ PROG = lzma -CXX = g++ -O2 -# -Wall -Werror -Wno-delete-non-virtual-dtor -CXX_C = gcc -O2 -Wall -Werror -ifdef SystemDrive -IS_MINGW = 1 -endif +# IS_X64 = 1 +# USE_ASM = 1 +# ST_MODE = 1 -ifdef IS_MINGW - -RM = del -CFLAGS = -c -LIB2 = -loleaut32 -luuid -LDFLAGS = -s +include ../../LzmaDec_gcc.mak -FILE_IO =FileIO -FILE_IO_2 =Windows/$(FILE_IO) +LOCAL_FLAGS_ST = +MT_OBJS = -MT_FILES = \ - LzFindMt.o \ - Threads.o \ +ifdef SystemDrive +IS_MINGW = 1 else - -RM = rm -f -CFLAGS = -c -D_7ZIP_ST - -FILE_IO =C_FileIO -FILE_IO_2 =Common/$(FILE_IO) - - +ifdef SYSTEMDRIVE +# ifdef OS +IS_MINGW = 1 +endif endif +ifdef ST_MODE -OBJS = \ - $(MT_FILES) \ - $(FILE_IO).o \ - LzmaAlone.o \ - Bench.o \ - BenchCon.o \ - ConsoleClose.o \ - LzmaDecoder.o \ - LzmaEncoder.o \ - LzmaRegister.o \ - CreateCoder.o \ - CWrappers.o \ - FileStreams.o \ - FilterCoder.o \ - MethodProps.o \ - StreamUtils.o \ - CommandLineParser.o \ - CRC.o \ - CrcReg.o \ - IntToString.o \ - MyString.o \ - MyVector.o \ - MyWindows.o \ - StringConvert.o \ - StringToInt.o \ - PropVariant.o \ - System.o \ - 7zCrc.o \ - 7zCrcOpt.o \ - Alloc.o \ - Bra86.o \ - CpuArch.o \ - LzFind.o \ - LzmaDec.o \ - LzmaEnc.o \ - Lzma86Dec.o \ - Lzma86Enc.o \ - - -all: $(PROG) - -$(PROG): $(OBJS) - $(CXX) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIB2) - -LzmaAlone.o: LzmaAlone.cpp - $(CXX) $(CFLAGS) LzmaAlone.cpp - -Bench.o: ../../UI/Common/Bench.cpp - $(CXX) $(CFLAGS) ../../UI/Common/Bench.cpp - -BenchCon.o: ../../UI/Console/BenchCon.cpp - $(CXX) $(CFLAGS) ../../UI/Console/BenchCon.cpp - -ConsoleClose.o: ../../UI/Console/ConsoleClose.cpp - $(CXX) $(CFLAGS) ../../UI/Console/ConsoleClose.cpp - -LzmaDecoder.o: ../../Compress/LzmaDecoder.cpp - $(CXX) $(CFLAGS) ../../Compress/LzmaDecoder.cpp - -LzmaEncoder.o: ../../Compress/LzmaEncoder.cpp - $(CXX) $(CFLAGS) ../../Compress/LzmaEncoder.cpp - -LzmaRegister.o: ../../Compress/LzmaRegister.cpp - $(CXX) $(CFLAGS) ../../Compress/LzmaRegister.cpp - -CreateCoder.o: ../../Common/CreateCoder.cpp - $(CXX) $(CFLAGS) ../../Common/CreateCoder.cpp - -CWrappers.o: ../../Common/CWrappers.cpp - $(CXX) $(CFLAGS) ../../Common/CWrappers.cpp - -FileStreams.o: ../../Common/FileStreams.cpp - $(CXX) $(CFLAGS) ../../Common/FileStreams.cpp - -FilterCoder.o: ../../Common/FilterCoder.cpp - $(CXX) $(CFLAGS) ../../Common/FilterCoder.cpp - -MethodProps.o: ../../Common/MethodProps.cpp - $(CXX) $(CFLAGS) ../../Common/MethodProps.cpp - -StreamUtils.o: ../../Common/StreamUtils.cpp - $(CXX) $(CFLAGS) ../../Common/StreamUtils.cpp - -$(FILE_IO).o: ../../../$(FILE_IO_2).cpp - $(CXX) $(CFLAGS) ../../../$(FILE_IO_2).cpp - - -CommandLineParser.o: ../../../Common/CommandLineParser.cpp - $(CXX) $(CFLAGS) ../../../Common/CommandLineParser.cpp - -CRC.o: ../../../Common/CRC.cpp - $(CXX) $(CFLAGS) ../../../Common/CRC.cpp - -CrcReg.o: ../../../Common/CrcReg.cpp - $(CXX) $(CFLAGS) ../../../Common/CrcReg.cpp - -IntToString.o: ../../../Common/IntToString.cpp - $(CXX) $(CFLAGS) ../../../Common/IntToString.cpp - -MyString.o: ../../../Common/MyString.cpp - $(CXX) $(CFLAGS) ../../../Common/MyString.cpp - -MyVector.o: ../../../Common/MyVector.cpp - $(CXX) $(CFLAGS) ../../../Common/MyVector.cpp +LOCAL_FLAGS_ST = -DZ7_ST -MyWindows.o: ../../../Common/MyWindows.cpp - $(CXX) $(CFLAGS) ../../../Common/MyWindows.cpp +else -StringConvert.o: ../../../Common/StringConvert.cpp - $(CXX) $(CFLAGS) ../../../Common/StringConvert.cpp +MT_OBJS = \ + $O/LzFindMt.o \ + $O/LzFindOpt.o \ + $O/Synchronization.o \ + $O/Threads.o \ -StringToInt.o: ../../../Common/StringToInt.cpp - $(CXX) $(CFLAGS) ../../../Common/StringToInt.cpp -PropVariant.o: ../../../Windows/PropVariant.cpp - $(CXX) $(CFLAGS) ../../../Windows/PropVariant.cpp -System.o: ../../../Windows/System.cpp - $(CXX) $(CFLAGS) ../../../Windows/System.cpp +endif -7zCrc.o: ../../../../C/7zCrc.c - $(CXX_C) $(CFLAGS) ../../../../C/7zCrc.c -7zCrcOpt.o: ../../../../C/7zCrcOpt.c - $(CXX_C) $(CFLAGS) ../../../../C/7zCrcOpt.c -Alloc.o: ../../../../C/Alloc.c - $(CXX_C) $(CFLAGS) ../../../../C/Alloc.c +LOCAL_FLAGS_SYS = -Bra86.o: ../../../../C/Bra86.c - $(CXX_C) $(CFLAGS) ../../../../C/Bra86.c +ifdef IS_MINGW -CpuArch.o: ../../../../C/CpuArch.c - $(CXX_C) $(CFLAGS) ../../../../C/CpuArch.c +SYS_OBJS = \ + $O/Registry.o \ + $O/resource.o \ -LzFind.o: ../../../../C/LzFind.c - $(CXX_C) $(CFLAGS) ../../../../C/LzFind.c +else -ifdef MT_FILES -LzFindMt.o: ../../../../C/LzFindMt.c - $(CXX_C) $(CFLAGS) ../../../../C/LzFindMt.c +SYS_OBJS = \ + $O/FileDir.o \ + $O/FileFind.o \ + $O/FileName.o \ + $O/MyWindows.o \ + $O/TimeUtils.o \ -Threads.o: ../../../../C/Threads.c - $(CXX_C) $(CFLAGS) ../../../../C/Threads.c endif -LzmaDec.o: ../../../../C/LzmaDec.c - $(CXX_C) $(CFLAGS) ../../../../C/LzmaDec.c - -LzmaEnc.o: ../../../../C/LzmaEnc.c - $(CXX_C) $(CFLAGS) ../../../../C/LzmaEnc.c - -Lzma86Dec.o: ../../../../C/Lzma86Dec.c - $(CXX_C) $(CFLAGS) ../../../../C/Lzma86Dec.c +LOCAL_FLAGS = \ + $(LOCAL_FLAGS_ST) \ + + +COMMON_OBJS = \ + $O/CommandLineParser.o \ + $O/CRC.o \ + $O/CrcReg.o \ + $O/IntToString.o \ + $O/LzFindPrepare.o \ + $O/MyString.o \ + $O/MyVector.o \ + $O/NewHandler.o \ + $O/StringConvert.o \ + $O/StringToInt.o \ + $O/UTFConvert.o \ + $O/Wildcard.o \ + +WIN_OBJS = \ + $O/FileIO.o \ + $O/PropVariant.o \ + $O/System.o \ + $O/SystemInfo.o \ + +COMPRESS_OBJS = \ + $O/LzmaDecoder.o \ + $O/LzmaEncoder.o \ + $O/LzmaRegister.o \ + +CONSOLE_OBJS = \ + $O/BenchCon.o \ + $O/ConsoleClose.o \ + +7ZIP_COMMON_OBJS = \ + $O/CreateCoder.o \ + $O/CWrappers.o \ + $O/FileStreams.o \ + $O/FilterCoder.o \ + $O/MethodProps.o \ + $O/StreamObjects.o \ + $O/StreamUtils.o \ + +C_OBJS = \ + $O/7zCrc.o \ + $O/7zCrcOpt.o \ + $O/Alloc.o \ + $O/Bra86.o \ + $O/CpuArch.o \ + $O/LzFind.o \ + $O/LzmaDec.o \ + $O/LzmaEnc.o \ + $O/Lzma86Dec.o \ + $O/Lzma86Enc.o \ -Lzma86Enc.o: ../../../../C/Lzma86Enc.c - $(CXX_C) $(CFLAGS) ../../../../C/Lzma86Enc.c - -clean: - -$(RM) $(PROG) $(OBJS) +OBJS = \ + $(LZMA_DEC_OPT_OBJS) \ + $(C_OBJS) \ + $(MT_OBJS) \ + $(SYS_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(COMPRESS_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(CONSOLE_OBJS) \ + $O/LzmaAlone.o \ + $O/Bench.o \ + +include ../../7zip_gcc.mak diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/SFXCon.dsp b/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/SFXCon.dsp index b21b9e841e5..1bb063dbc04 100644 --- a/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/SFXCon.dsp +++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/SFXCon.dsp @@ -42,7 +42,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "EXTRACT_ONLY" /D "_SFX" /D "NO_READ_FROM_CODER" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gr /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "Z7_EXTRACT_ONLY" /D "Z7_SFX" /D "Z7_NO_READ_FROM_CODER" /FAcs /Yu"StdAfx.h" /FD /c # ADD BASE RSC /l 0x419 /d "NDEBUG" # ADD RSC /l 0x419 /d "NDEBUG" BSC32=bscmake.exe @@ -67,7 +67,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /Gz /MTd /W4 /WX /Gm /GX /ZI /Od /I "..\..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "EXTRACT_ONLY" /D "_SFX" /D "NO_READ_FROM_CODER" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W4 /WX /Gm /GX /ZI /Od /I "..\..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "Z7_EXTRACT_ONLY" /D "Z7_SFX" /D "Z7_NO_READ_FROM_CODER" /Yu"StdAfx.h" /FD /GZ /c # ADD BASE RSC /l 0x419 /d "_DEBUG" # ADD RSC /l 0x419 /d "_DEBUG" BSC32=bscmake.exe @@ -117,6 +117,10 @@ SOURCE=..\..\Archive\Common\CoderMixer2.h # End Source File # Begin Source File +SOURCE=..\..\Archive\Common\HandlerOut.h +# End Source File +# Begin Source File + SOURCE=..\..\Archive\Common\ItemNameUtils.cpp # End Source File # Begin Source File @@ -253,6 +257,10 @@ SOURCE=..\..\Compress\Bcj2Coder.cpp # End Source File # Begin Source File +SOURCE=..\..\Compress\Bcj2Coder.h +# End Source File +# Begin Source File + SOURCE=..\..\Compress\Bcj2Register.cpp # End Source File # Begin Source File @@ -261,6 +269,10 @@ SOURCE=..\..\Compress\BcjCoder.cpp # End Source File # Begin Source File +SOURCE=..\..\Compress\BcjCoder.h +# End Source File +# Begin Source File + SOURCE=..\..\Compress\BcjRegister.cpp # End Source File # Begin Source File @@ -281,6 +293,10 @@ SOURCE=..\..\Compress\CopyCoder.cpp # End Source File # Begin Source File +SOURCE=..\..\Compress\CopyCoder.h +# End Source File +# Begin Source File + SOURCE=..\..\Compress\CopyRegister.cpp # End Source File # Begin Source File @@ -293,6 +309,10 @@ SOURCE=..\..\Compress\Lzma2Decoder.cpp # End Source File # Begin Source File +SOURCE=..\..\Compress\Lzma2Decoder.h +# End Source File +# Begin Source File + SOURCE=..\..\Compress\Lzma2Register.cpp # End Source File # Begin Source File @@ -301,6 +321,10 @@ SOURCE=..\..\Compress\LzmaDecoder.cpp # End Source File # Begin Source File +SOURCE=..\..\Compress\LzmaDecoder.h +# End Source File +# Begin Source File + SOURCE=..\..\Compress\LzmaRegister.cpp # End Source File # Begin Source File @@ -309,6 +333,10 @@ SOURCE=..\..\Compress\PpmdDecoder.cpp # End Source File # Begin Source File +SOURCE=..\..\Compress\PpmdDecoder.h +# End Source File +# Begin Source File + SOURCE=..\..\Compress\PpmdRegister.cpp # End Source File # End Group @@ -411,6 +439,14 @@ SOURCE=..\..\..\Windows\Synchronization.cpp SOURCE=..\..\..\Windows\Synchronization.h # End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\System.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\System.h +# End Source File # End Group # Begin Group "Common" @@ -425,6 +461,10 @@ SOURCE=..\..\..\Common\CommandLineParser.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\Common.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\CRC.cpp # End Source File # Begin Source File @@ -441,6 +481,18 @@ SOURCE=..\..\..\Common\IntToString.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\MyBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyBuffer2.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyCom.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\MyString.cpp # End Source File # Begin Source File @@ -465,6 +517,10 @@ SOURCE=..\..\..\Common\NewHandler.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\Sha256Prepare.cpp +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\StdInStream.cpp # End Source File # Begin Source File @@ -739,6 +795,19 @@ SOURCE=..\..\..\..\C\7zCrcOpt.c # End Source File # Begin Source File +SOURCE=..\..\..\..\C\7zStream.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zTypes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zWindows.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\Aes.c # SUBTRACT CPP /YX /Yc /Yu # End Source File @@ -790,11 +859,19 @@ SOURCE=..\..\..\..\C\BraIA64.c # End Source File # Begin Source File +SOURCE=..\..\..\..\C\Compiler.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\CpuArch.c # SUBTRACT CPP /YX /Yc /Yu # End Source File # Begin Source File +SOURCE=..\..\..\..\C\CpuArch.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\Delta.c # SUBTRACT CPP /YX /Yc /Yu # End Source File @@ -805,7 +882,18 @@ SOURCE=..\..\..\..\C\Delta.h # Begin Source File SOURCE=..\..\..\..\C\DllSecur.c + +!IF "$(CFG)" == "SFXCon - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "SFXCon - Win32 Debug" + # SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + # End Source File # Begin Source File @@ -822,6 +910,15 @@ SOURCE=..\..\..\..\C\Lzma2Dec.h # End Source File # Begin Source File +SOURCE=..\..\..\..\C\Lzma2DecMt.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2DecMt.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\LzmaDec.c # SUBTRACT CPP /YX /Yc /Yu # End Source File @@ -831,6 +928,15 @@ SOURCE=..\..\..\..\C\LzmaDec.h # End Source File # Begin Source File +SOURCE=..\..\..\..\C\MtDec.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\MtDec.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\Ppmd7.c # SUBTRACT CPP /YX /Yc /Yu # End Source File @@ -854,6 +960,11 @@ SOURCE=..\..\..\..\C\Sha256.h # End Source File # Begin Source File +SOURCE=..\..\..\..\C\Sha256Opt.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\Threads.c # SUBTRACT CPP /YX /Yc /Yu # End Source File @@ -862,13 +973,33 @@ SOURCE=..\..\..\..\C\Threads.c SOURCE=..\..\..\..\C\Threads.h # End Source File # End Group +# Begin Group "7zip" + +# PROP Default_Filter "" # Begin Source File -SOURCE=.\7z.ico +SOURCE=..\..\Archive\IArchive.h # End Source File # Begin Source File -SOURCE=..\..\Archive\IArchive.h +SOURCE=..\..\ICoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\IDecl.h +# End Source File +# Begin Source File + +SOURCE=..\..\IPassword.h +# End Source File +# Begin Source File + +SOURCE=..\..\IProgress.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\7z.ico # End Source File # Begin Source File diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/SfxCon.cpp b/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/SfxCon.cpp index d828922f314..cfce24d95f9 100644 --- a/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/SfxCon.cpp +++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/SfxCon.cpp @@ -2,8 +2,10 @@ #include "StdAfx.h" -#include "../../../Common/MyWindows.h" +#include "../../../../C/CpuArch.h" +#include "../../../../C/DllSecur.h" +#include "../../../Common/MyWindows.h" #include "../../../Common/MyInitGuid.h" #include "../../../Common/CommandLineParser.h" @@ -11,8 +13,10 @@ #ifdef _WIN32 #include "../../../Windows/DLL.h" -#include "../../../Windows/FileDir.h" +#else +#include "../../../Common/StringConvert.h" #endif +#include "../../../Windows/FileDir.h" #include "../../../Windows/FileName.h" #include "../../UI/Common/ExitCode.h" @@ -24,7 +28,6 @@ #include "../../MyVersion.h" -#include "../../../../C/DllSecur.h" using namespace NWindows; using namespace NFile; @@ -32,13 +35,17 @@ using namespace NDir; using namespace NCommandLineParser; #ifdef _WIN32 -HINSTANCE g_hInstance = 0; +extern +HINSTANCE g_hInstance; +HINSTANCE g_hInstance = NULL; #endif +extern +int g_CodePage; int g_CodePage = -1; extern CStdOutStream *g_StdStream; -static const char *kCopyrightString = -"\n7-Zip SFX " MY_VERSION_COPYRIGHT_DATE "\n"; +static const char * const kCopyrightString = +"\n7-Zip SFX " MY_VERSION_CPU " : " MY_COPYRIGHT_DATE "\n"; static const int kNumSwitches = 6; @@ -65,7 +72,6 @@ enum EEnum } /* static const char kRecursedIDChar = 'R'; -static const wchar_t *kRecursedPostCharSet = L"0-"; namespace NRecursedPostCharIndex { enum EEnum @@ -81,14 +87,20 @@ static const char kImmediateNameID = '!'; static const char kSomeCludePostStringMinSize = 2; // at least <@|!><N>ame must be static const char kSomeCludeAfterRecursedPostStringMinSize = 2; // at least <@|!><N>ame must be */ + +#define SWFRM_3(t, mu, mi) t, mu, mi, NULL +#define SWFRM_1(t) SWFRM_3(t, false, 0) +#define SWFRM_SIMPLE SWFRM_1(NSwitchType::kSimple) +#define SWFRM_STRING_SINGL(mi) SWFRM_3(NSwitchType::kString, false, mi) + static const CSwitchForm kSwitchForms[kNumSwitches] = { - { "?", NSwitchType::kSimple }, - { "H", NSwitchType::kSimple }, - { "BD", NSwitchType::kSimple }, - { "Y", NSwitchType::kSimple }, - { "P", NSwitchType::kString, false, 1 }, - { "O", NSwitchType::kString, false, 1 }, + { "?", SWFRM_SIMPLE }, + { "H", SWFRM_SIMPLE }, + { "BD", SWFRM_SIMPLE }, + { "Y", SWFRM_SIMPLE }, + { "P", SWFRM_STRING_SINGL(1) }, + { "O", SWFRM_STRING_SINGL(1) }, }; static const int kNumCommandForms = 3; @@ -101,10 +113,9 @@ static const NRecursedType::EEnum kCommandRecursedDefault[kNumCommandForms] = // static const bool kTestExtractRecursedDefault = true; // static const bool kAddRecursedDefault = false; -static const wchar_t *kUniversalWildcard = L"*"; -static const int kCommandIndex = 0; +static const char * const kUniversalWildcard = "*"; -static const char *kHelpString = +static const char * const kHelpString = "\nUsage: 7zSFX [<command>] [<switches>...] [<file_name>...]\n" "\n" "<Commands>\n" @@ -121,16 +132,16 @@ static const char *kHelpString = // --------------------------- // exception messages -static const char *kUserErrorMessage = "Incorrect command line"; // NExitCode::kUserError -// static const char *kIncorrectListFile = "Incorrect wildcard in listfile"; -static const char *kIncorrectWildcardInCommandLine = "Incorrect wildcard in command line"; +static const char * const kUserErrorMessage = "Incorrect command line"; // NExitCode::kUserError +// static const char * const kIncorrectListFile = "Incorrect wildcard in listfile"; +static const char * const kIncorrectWildcardInCommandLine = "Incorrect wildcard in command line"; // static const CSysString kFileIsNotArchiveMessageBefore = "File \""; // static const CSysString kFileIsNotArchiveMessageAfter = "\" is not archive"; -// static const char *kProcessArchiveMessage = " archive: "; +// static const char * const kProcessArchiveMessage = " archive: "; -static const char *kCantFindSFX = " cannot find sfx"; +static const char * const kCantFindSFX = " cannot find sfx"; namespace NCommandType { @@ -151,7 +162,7 @@ struct CArchiveCommand NRecursedType::EEnum DefaultRecursedType() const; }; -bool ParseArchiveCommand(const UString &commandString, CArchiveCommand &command) +static bool ParseArchiveCommand(const UString &commandString, CArchiveCommand &command) { UString s = commandString; s.MakeLower_Ascii(); @@ -171,17 +182,19 @@ NRecursedType::EEnum CArchiveCommand::DefaultRecursedType() const return kCommandRecursedDefault[CommandType]; } -void PrintHelp(void) +static void PrintHelp(void) { g_StdOut << kHelpString; } +Z7_ATTR_NORETURN static void ShowMessageAndThrowException(const char *message, NExitCode::EEnum code) { g_StdOut << message << endl; throw code; } +Z7_ATTR_NORETURN static void PrintHelpAndExit() // yyy { PrintHelp(); @@ -198,7 +211,7 @@ static bool AddNameToCensor(NWildcard::CCensor &wildcardCensor, if (!IsWildcardFilePathLegal(name)) return false; */ - bool isWildcard = DoesNameContainWildcard(name); + const bool isWildcard = DoesNameContainWildcard(name); bool recursed = false; switch (type) @@ -213,11 +226,14 @@ static bool AddNameToCensor(NWildcard::CCensor &wildcardCensor, recursed = false; break; } - wildcardCensor.AddPreItem(include, name, recursed, true); + + NWildcard::CCensorPathProps props; + props.Recursive = recursed; + wildcardCensor.AddPreItem(include, name, props); return true; } -void AddCommandLineWildcardToCensor(NWildcard::CCensor &wildcardCensor, +static void AddCommandLineWildcardToCensor(NWildcard::CCensor &wildcardCensor, const UString &name, bool include, NRecursedType::EEnum type) { if (!AddNameToCensor(wildcardCensor, name, include, type)) @@ -226,7 +242,7 @@ void AddCommandLineWildcardToCensor(NWildcard::CCensor &wildcardCensor, #ifndef _WIN32 -static void GetArguments(int numArgs, const char *args[], UStringVector &parts) +static void GetArguments(int numArgs, char *args[], UStringVector &parts) { parts.Clear(); for (int i = 0; i < numArgs; i++) @@ -237,9 +253,15 @@ static void GetArguments(int numArgs, const char *args[], UStringVector &parts) } #endif + int Main2( #ifndef _WIN32 - int numArgs, const char *args[] + int numArgs, char *args[] + #endif +); +int Main2( + #ifndef _WIN32 + int numArgs, char *args[] #endif ) { @@ -252,6 +274,10 @@ int Main2( SetFileApisToOEM(); #endif + #ifdef ENV_HAVE_LOCALE + MY_SetLocale(); + #endif + g_StdOut << kCopyrightString; UStringVector commandStrings; @@ -276,17 +302,23 @@ int Main2( #else - UString arcPath = commandStrings.Front(); + if (commandStrings.IsEmpty()) + return NExitCode::kFatalError; + + const FString arcPath = us2fs(commandStrings.Front()); #endif - commandStrings.Delete(0); + #ifndef UNDER_CE + if (commandStrings.Size() > 0) + commandStrings.Delete(0); + #endif - NCommandLineParser::CParser parser(kNumSwitches); + NCommandLineParser::CParser parser; try { - if (!parser.ParseStrings(kSwitchForms, commandStrings)) + if (!parser.ParseStrings(kSwitchForms, kNumSwitches, commandStrings)) { g_StdOut << "Command line error:" << endl << parser.ErrorMessage << endl @@ -331,7 +363,7 @@ int Main2( { if (nonSwitchStrings.Size() == curCommandIndex) - AddCommandLineWildcardToCensor(wildcardCensor, kUniversalWildcard, true, recursedType); + AddCommandLineWildcardToCensor(wildcardCensor, (UString)kUniversalWildcard, true, recursedType); for (; curCommandIndex < nonSwitchStrings.Size(); curCommandIndex++) { const UString &s = nonSwitchStrings[curCommandIndex]; @@ -341,18 +373,18 @@ int Main2( } } - bool yesToAll = parser[NKey::kYes].ThereIs; + const bool yesToAll = parser[NKey::kYes].ThereIs; // NExtractMode::EEnum extractMode; // bool isExtractGroupCommand = command.IsFromExtractGroup(extractMode); - bool passwordEnabled = parser[NKey::kPassword].ThereIs; + const bool passwordEnabled = parser[NKey::kPassword].ThereIs; UString password; if (passwordEnabled) password = parser[NKey::kPassword].PostStrings[0]; - if (!NFind::DoesFileExist(arcPath)) + if (!NFind::DoesFileExist_FollowLink(arcPath)) throw kCantFindSFX; FString outputDir; @@ -374,7 +406,7 @@ int Main2( CCodecs *codecs = new CCodecs; CMyComPtr< - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS ICompressCodecsInfo #else IUnknown @@ -392,7 +424,7 @@ int Main2( CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs; ecs->Init(g_StdStream, &g_StdErr, g_StdStream); - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO ecs->PasswordIsDefined = passwordEnabled; ecs->Password = password; #endif @@ -401,7 +433,7 @@ int Main2( COpenCallbackConsole openCallback; openCallback.Init(g_StdStream, g_StdStream); - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO openCallback.PasswordIsDefined = passwordEnabled; openCallback.Password = password; #endif @@ -423,22 +455,33 @@ int Main2( codecs, CObjectVector<COpenType>(), CIntVector(), v1, v2, wildcardCensorHead, - eo, ecs, ecs, + eo, + ecs, ecs, ecs, // NULL, // hash errorMessage, stat); + + ecs->ClosePercents(); + if (!errorMessage.IsEmpty()) { - (*g_StdStream) << endl << "Error: " << errorMessage;; + (*g_StdStream) << endl << "Error: " << errorMessage; if (result == S_OK) result = E_FAIL; } - if (ecs->NumArcsWithError != 0 || ecs->NumFileErrors != 0) + if ( 0 != ecs->NumCantOpenArcs + || 0 != ecs->NumArcsWithError + || 0 != ecs->NumFileErrors + || 0 != ecs->NumOpenArcErrors) { + if (ecs->NumCantOpenArcs != 0) + (*g_StdStream) << endl << "Can't open as archive" << endl; if (ecs->NumArcsWithError != 0) (*g_StdStream) << endl << "Archive Errors" << endl; if (ecs->NumFileErrors != 0) (*g_StdStream) << endl << "Sub items Errors: " << ecs->NumFileErrors << endl; + if (ecs->NumOpenArcErrors != 0) + (*g_StdStream) << endl << "Open Errors: " << ecs->NumOpenArcErrors << endl; return NExitCode::kFatalError; } if (result != S_OK) @@ -460,7 +503,7 @@ int Main2( wildcardCensorHead, true, // enableHeaders false, // techMode - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO passwordEnabled, password, #endif numErrors, numWarnings); diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/StdAfx.h b/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/StdAfx.h index 2854ff3e935..035267ccd02 100644 --- a/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/StdAfx.h +++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/StdAfx.h @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../../Common/Common.h" #endif diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/makefile b/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/makefile index 4c201c00a70..51aaf51658d 100644 --- a/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/makefile +++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/makefile @@ -1,10 +1,11 @@ PROG = 7zCon.sfx MY_CONSOLE = 1 +MY_FIXED = 1 + CFLAGS = $(CFLAGS) \ - -DEXTRACT_ONLY \ - -DNO_READ_FROM_CODER \ - -D_SFX \ - -D_CONSOLE \ + -DZ7_EXTRACT_ONLY \ + -DZ7_NO_READ_FROM_CODER \ + -DZ7_SFX \ CURRENT_OBJS = \ $O\SfxCon.obj \ @@ -28,8 +29,8 @@ COMMON_OBJS = \ $O\StdInStream.obj \ $O\StdOutStream.obj \ $O\StringConvert.obj \ - $O\Wildcard.obj \ $O\UTFConvert.obj \ + $O\Wildcard.obj \ WIN_OBJS = \ $O\DLL.obj \ @@ -41,6 +42,7 @@ WIN_OBJS = \ $O\PropVariant.obj \ $O\PropVariantConv.obj \ $O\Synchronization.obj \ + $O\System.obj \ 7ZIP_COMMON_OBJS = \ $O\CreateCoder.obj \ @@ -62,9 +64,9 @@ UI_COMMON_OBJS = \ $O\ArchiveExtractCallback.obj \ $O\ArchiveOpenCallback.obj \ $O\DefaultName.obj \ - $O\LoadCodecs.obj \ $O\Extract.obj \ $O\ExtractingFilePath.obj \ + $O\LoadCodecs.obj \ $O\OpenArchive.obj \ $O\PropIDUtils.obj \ @@ -77,7 +79,6 @@ AR_COMMON_OBJS = \ $O\MultiStream.obj \ $O\OutStreamWithCRC.obj \ - 7Z_OBJS = \ $O\7zDecode.obj \ $O\7zExtract.obj \ @@ -108,6 +109,7 @@ CRYPTO_OBJS = \ $O\MyAes.obj \ C_OBJS = \ + $O\7zStream.obj \ $O\Alloc.obj \ $O\Bcj2.obj \ $O\Bra.obj \ @@ -117,13 +119,16 @@ C_OBJS = \ $O\Delta.obj \ $O\DllSecur.obj \ $O\Lzma2Dec.obj \ + $O\Lzma2DecMt.obj \ $O\LzmaDec.obj \ + $O\MtDec.obj \ $O\Ppmd7.obj \ $O\Ppmd7Dec.obj \ - $O\Sha256.obj \ $O\Threads.obj \ !include "../../Aes.mak" !include "../../Crc.mak" +!include "../../LzmaDec.mak" +!include "../../Sha256.mak" !include "../../7zip.mak" diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/makefile.gcc b/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/makefile.gcc new file mode 100644 index 00000000000..9278502d9c3 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/makefile.gcc @@ -0,0 +1,213 @@ +PROG = 7zCon + +# IS_X64 = 1 +# USE_ASM = 1 +# ST_MODE = 1 + +include ../../LzmaDec_gcc.mak + + +LOCAL_FLAGS_ST = +MT_OBJS = + + +ifdef SystemDrive +IS_MINGW = 1 +else +ifdef SYSTEMDRIVE +# ifdef OS +IS_MINGW = 1 +endif +endif + +ifdef ST_MODE + +LOCAL_FLAGS_ST = -DZ7_ST + +ifdef IS_MINGW +MT_OBJS = \ + $O/Threads.o \ + +endif + +else + +MT_OBJS = \ + $O/StreamBinder.o \ + $O/Synchronization.o \ + $O/VirtThread.o \ + $O/Threads.o \ + +endif + + + +LOCAL_FLAGS_SYS = + +ifdef IS_MINGW + +LOCAL_FLAGS_SYS = \ + +SYS_OBJS = \ + $O/DLL.o \ + $O/DllSecur.o \ + $O/resource.o \ + +else + +SYS_OBJS = \ + $O/MyWindows.o \ + +endif + +LOCAL_FLAGS = \ + $(LOCAL_FLAGS_ST) \ + $(LOCAL_FLAGS_SYS) \ + -DZ7_EXTRACT_ONLY \ + -DZ7_NO_READ_FROM_CODER \ + -DZ7_SFX \ + + +CURRENT_OBJS = \ + $O/SfxCon.o \ + +CONSOLE_OBJS = \ + $O/ConsoleClose.o \ + $O/ExtractCallbackConsole.o \ + $O/List.o \ + $O/MainAr.o \ + $O/OpenCallbackConsole.o \ + $O/PercentPrinter.o \ + $O/UserInputUtils.o \ + +COMMON_OBJS = \ + $O/CommandLineParser.o \ + $O/CRC.o \ + $O/IntToString.o \ + $O/MyString.o \ + $O/MyVector.o \ + $O/NewHandler.o \ + $O/Sha256Prepare.o \ + $O/StdInStream.o \ + $O/StdOutStream.o \ + $O/StringConvert.o \ + $O/UTFConvert.o \ + $O/Wildcard.o \ + +WIN_OBJS = \ + \ + $O/ErrorMsg.o \ + $O/FileDir.o \ + $O/FileFind.o \ + $O/FileIO.o \ + $O/FileName.o \ + $O/PropVariant.o \ + $O/PropVariantConv.o \ + \ + $O/System.o \ + $O/TimeUtils.o \ + +7ZIP_COMMON_OBJS = \ + $O/CreateCoder.o \ + $O/CWrappers.o \ + $O/FilePathAutoRename.o \ + $O/FileStreams.o \ + $O/InBuffer.o \ + $O/FilterCoder.o \ + $O/LimitedStreams.o \ + $O/OutBuffer.o \ + $O/ProgressUtils.o \ + $O/PropId.o \ + \ + $O/StreamObjects.o \ + $O/StreamUtils.o \ + \ + +UI_COMMON_OBJS = \ + $O/ArchiveExtractCallback.o \ + $O/ArchiveOpenCallback.o \ + $O/DefaultName.o \ + $O/Extract.o \ + $O/ExtractingFilePath.o \ + $O/LoadCodecs.o \ + $O/OpenArchive.o \ + $O/PropIDUtils.o \ + +AR_OBJS = \ + $O/SplitHandler.o \ + +AR_COMMON_OBJS = \ + $O/CoderMixer2.o \ + $O/ItemNameUtils.o \ + $O/MultiStream.o \ + $O/OutStreamWithCRC.o \ + +7Z_OBJS = \ + $O/7zDecode.o \ + $O/7zExtract.o \ + $O/7zHandler.o \ + $O/7zIn.o \ + $O/7zRegister.o \ + +COMPRESS_OBJS = \ + $O/Bcj2Coder.o \ + $O/Bcj2Register.o \ + $O/BcjCoder.o \ + $O/BcjRegister.o \ + $O/BranchMisc.o \ + $O/BranchRegister.o \ + $O/CopyCoder.o \ + $O/CopyRegister.o \ + $O/DeltaFilter.o \ + $O/Lzma2Decoder.o \ + $O/Lzma2Register.o \ + $O/LzmaDecoder.o \ + $O/LzmaRegister.o \ + $O/PpmdDecoder.o \ + $O/PpmdRegister.o \ + +CRYPTO_OBJS = \ + $O/7zAes.o \ + $O/7zAesRegister.o \ + $O/MyAes.o \ + +C_OBJS = \ + $O/7zStream.o \ + $O/Alloc.o \ + $O/Bcj2.o \ + $O/Bra.o \ + $O/Bra86.o \ + $O/BraIA64.o \ + $O/CpuArch.o \ + $O/Delta.o \ + $O/Lzma2Dec.o \ + $O/Lzma2DecMt.o \ + $O/LzmaDec.o \ + $O/MtDec.o \ + $O/Ppmd7.o \ + $O/Ppmd7Dec.o \ + $O/Sha256.o \ + $O/Sha256Opt.o \ + $O/7zCrc.o \ + $O/7zCrcOpt.o \ + $O/Aes.o \ + $O/AesOpt.o \ + +OBJS = \ + $(LZMA_DEC_OPT_OBJS) \ + $(C_OBJS) \ + $(MT_OBJS) \ + $(SYS_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(COMPRESS_OBJS) \ + $(CRYPTO_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(AR_OBJS) \ + $(AR_COMMON_OBJS) \ + $(7Z_OBJS) \ + $(UI_COMMON_OBJS) \ + $(CONSOLE_OBJS) \ + $(CURRENT_OBJS) \ + +include ../../7zip_gcc.mak diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/resource.rc b/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/resource.rc index 58331b81f8f..65762125a25 100644 --- a/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/resource.rc +++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXCon/resource.rc @@ -2,4 +2,8 @@ MY_VERSION_INFO_APP("7z Console SFX", "7z.sfx") -101 ICON "7z.ico"
\ No newline at end of file +101 ICON "7z.ico" + +#ifndef UNDER_CE +1 24 MOVEABLE PURE "../../UI/Console/Console.manifest" +#endif diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp index 793306303c5..9d632ee04f3 100644 --- a/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp +++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp @@ -15,9 +15,9 @@ using namespace NWindows; using namespace NFile; using namespace NDir; -static LPCWSTR kCantDeleteFile = L"Can not delete output file"; -static LPCWSTR kCantOpenFile = L"Can not open output file"; -static LPCWSTR kUnsupportedMethod = L"Unsupported Method"; +static LPCSTR const kCantDeleteFile = "Cannot delete output file"; +static LPCSTR const kCantOpenFile = "Cannot open output file"; +static LPCSTR const kUnsupportedMethod = "Unsupported Method"; void CExtractCallbackImp::Init(IInArchive *archiveHandler, const FString &directoryPath, @@ -63,7 +63,7 @@ HRESULT CExtractCallbackImp::Open_Finished() return S_OK; } -STDMETHODIMP CExtractCallbackImp::SetTotal(UInt64 size) +Z7_COM7F_IMF(CExtractCallbackImp::SetTotal(UInt64 size)) { #ifndef _NO_PROGRESS ProgressDialog.Sync.SetProgress(size, 0); @@ -71,10 +71,10 @@ STDMETHODIMP CExtractCallbackImp::SetTotal(UInt64 size) return S_OK; } -STDMETHODIMP CExtractCallbackImp::SetCompleted(const UInt64 *completeValue) +Z7_COM7F_IMF(CExtractCallbackImp::SetCompleted(const UInt64 *completeValue)) { #ifndef _NO_PROGRESS - RINOK(ProgressDialog.Sync.ProcessStopAndPause()); + RINOK(ProgressDialog.Sync.ProcessStopAndPause()) if (completeValue != NULL) ProgressDialog.Sync.SetPos(*completeValue); #endif @@ -92,8 +92,8 @@ void CExtractCallbackImp::CreateComplexDirectory(const UStringVector &dirPathPar } } -STDMETHODIMP CExtractCallbackImp::GetStream(UInt32 index, - ISequentialOutStream **outStream, Int32 askExtractMode) +Z7_COM7F_IMF(CExtractCallbackImp::GetStream(UInt32 index, + ISequentialOutStream **outStream, Int32 askExtractMode)) { #ifndef _NO_PROGRESS if (ProgressDialog.Sync.GetStopped()) @@ -104,7 +104,7 @@ STDMETHODIMP CExtractCallbackImp::GetStream(UInt32 index, UString fullPath; { NCOM::CPropVariant prop; - RINOK(_archiveHandler->GetProperty(index, kpidPath, &prop)); + RINOK(_archiveHandler->GetProperty(index, kpidPath, &prop)) if (prop.vt == VT_EMPTY) fullPath = _itemDefaultName; else @@ -119,7 +119,7 @@ STDMETHODIMP CExtractCallbackImp::GetStream(UInt32 index, if (askExtractMode == NArchive::NExtract::NAskMode::kExtract) { NCOM::CPropVariant prop; - RINOK(_archiveHandler->GetProperty(index, kpidAttrib, &prop)); + RINOK(_archiveHandler->GetProperty(index, kpidAttrib, &prop)) if (prop.vt == VT_EMPTY) _processedFileInfo.Attributes = _defaultAttributes; else @@ -129,18 +129,18 @@ STDMETHODIMP CExtractCallbackImp::GetStream(UInt32 index, _processedFileInfo.Attributes = prop.ulVal; } - RINOK(_archiveHandler->GetProperty(index, kpidIsDir, &prop)); + RINOK(_archiveHandler->GetProperty(index, kpidIsDir, &prop)) _processedFileInfo.IsDir = VARIANT_BOOLToBool(prop.boolVal); bool isAnti = false; { NCOM::CPropVariant propTemp; - RINOK(_archiveHandler->GetProperty(index, kpidIsAnti, &propTemp)); + RINOK(_archiveHandler->GetProperty(index, kpidIsAnti, &propTemp)) if (propTemp.vt == VT_BOOL) isAnti = VARIANT_BOOLToBool(propTemp.boolVal); } - RINOK(_archiveHandler->GetProperty(index, kpidMTime, &prop)); + RINOK(_archiveHandler->GetProperty(index, kpidMTime, &prop)) switch (prop.vt) { case VT_EMPTY: _processedFileInfo.MTime = _defaultMTime; break; @@ -207,13 +207,13 @@ STDMETHODIMP CExtractCallbackImp::GetStream(UInt32 index, return S_OK; } -STDMETHODIMP CExtractCallbackImp::PrepareOperation(Int32 askExtractMode) +Z7_COM7F_IMF(CExtractCallbackImp::PrepareOperation(Int32 askExtractMode)) { _extractMode = (askExtractMode == NArchive::NExtract::NAskMode::kExtract); return S_OK; } -STDMETHODIMP CExtractCallbackImp::SetOperationResult(Int32 resultEOperationResult) +Z7_COM7F_IMF(CExtractCallbackImp::SetOperationResult(Int32 resultEOperationResult)) { switch (resultEOperationResult) { @@ -237,7 +237,7 @@ STDMETHODIMP CExtractCallbackImp::SetOperationResult(Int32 resultEOperationResul if (_outFileStream != NULL) { _outFileStreamSpec->SetMTime(&_processedFileInfo.MTime); - RINOK(_outFileStreamSpec->Close()); + RINOK(_outFileStreamSpec->Close()) } _outFileStream.Release(); if (_extractMode) diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.h b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.h index cfbc5c07aa0..b9377ae6551 100644 --- a/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.h +++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.h @@ -1,7 +1,7 @@ // ExtractCallbackSfx.h -#ifndef __EXTRACT_CALLBACK_SFX_H -#define __EXTRACT_CALLBACK_SFX_H +#ifndef ZIP7_INC_EXTRACT_CALLBACK_SFX_H +#define ZIP7_INC_EXTRACT_CALLBACK_SFX_H #include "resource.h" @@ -19,19 +19,16 @@ #endif #include "../../UI/Common/ArchiveOpenCallback.h" -class CExtractCallbackImp: +class CExtractCallbackImp Z7_final: public IArchiveExtractCallback, public IOpenCallbackUI, public CMyUnknownImp { -public: - - MY_UNKNOWN_IMP - - INTERFACE_IArchiveExtractCallback(;) - INTERFACE_IOpenCallbackUI(;) + Z7_COM_UNKNOWN_IMP_0 + Z7_IFACE_COM7_IMP(IProgress) + Z7_IFACE_COM7_IMP(IArchiveExtractCallback) + Z7_IFACE_IMP(IOpenCallbackUI) -private: CMyComPtr<IInArchive> _archiveHandler; FString _directoryPath; UString _filePath; @@ -70,7 +67,7 @@ public: #ifndef _NO_PROGRESS HRESULT StartProgressDialog(const UString &title, NWindows::CThread &thread) { - ProgressDialog.Create(title, thread, 0); + ProgressDialog.Create(title, thread, NULL); { ProgressDialog.SetText(LangString(IDS_PROGRESS_EXTRACTING)); } @@ -78,7 +75,7 @@ public: ProgressDialog.Show(SW_SHOWNORMAL); return S_OK; } - virtual ~CExtractCallbackImp() { ProgressDialog.Destroy(); } + ~CExtractCallbackImp() { ProgressDialog.Destroy(); } #endif }; diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp index b1592993857..73ccff1b7d4 100644 --- a/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp +++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp @@ -18,8 +18,8 @@ using namespace NWindows; using namespace NFile; using namespace NDir; -static LPCWSTR kCantFindArchive = L"Can not find archive file"; -static LPCWSTR kCantOpenArchive = L"Can not open the file as archive"; +static LPCSTR const kCantFindArchive = "Cannot find archive file"; +static LPCSTR const kCantOpenArchive = "Cannot open the file as archive"; struct CThreadExtracting { @@ -64,18 +64,14 @@ struct CThreadExtracting if (!CreateComplexDir(dirPath)) { - ErrorMessage = MyFormatNew(IDS_CANNOT_CREATE_FOLDER, - #ifdef LANG - 0x02000603, - #endif - fs2us(dirPath)); + ErrorMessage = MyFormatNew(IDS_CANNOT_CREATE_FOLDER, fs2us(dirPath)); Result = E_FAIL; return; } - ExtractCallbackSpec->Init(ArchiveLink.GetArchive(), dirPath, L"Default", fi.MTime, 0); + ExtractCallbackSpec->Init(ArchiveLink.GetArchive(), dirPath, (UString)"Default", fi.MTime, 0); - Result = ArchiveLink.GetArchive()->Extract(0, (UInt32)(Int32)-1 , BoolToInt(false), ExtractCallback); + Result = ArchiveLink.GetArchive()->Extract(NULL, (UInt32)(Int32)-1 , BoolToInt(false), ExtractCallback); } void Process() @@ -116,7 +112,9 @@ HRESULT ExtractArchive(CCodecs *codecs, const FString &fileName, const FString & { t.ExtractCallbackSpec->ProgressDialog.IconID = IDI_ICON; NWindows::CThread thread; - RINOK(thread.Create(CThreadExtracting::MyThreadFunction, &t)); + const WRes wres = thread.Create(CThreadExtracting::MyThreadFunction, &t); + if (wres != 0) + return HRESULT_FROM_WIN32(wres); UString title; LangString(IDS_PROGRESS_EXTRACTING, title); diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/ExtractEngine.h b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/ExtractEngine.h index 295d77b9957..b7f79657903 100644 --- a/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/ExtractEngine.h +++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/ExtractEngine.h @@ -1,7 +1,7 @@ // ExtractEngine.h -#ifndef __EXTRACT_ENGINE_H -#define __EXTRACT_ENGINE_H +#ifndef ZIP7_INC_EXTRACT_ENGINE_H +#define ZIP7_INC_EXTRACT_ENGINE_H #include "../../UI/Common/LoadCodecs.h" diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp index 787c1bdefc5..cf96460fcc5 100644 --- a/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp +++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp @@ -44,7 +44,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /Gz /MT /W4 /WX /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "NO_REGISTRY" /D "_SFX" /D "_NO_CRYPTO" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gz /MT /W4 /WX /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "Z7_EXTRACT_ONLY" /D "Z7_NO_REGISTRY" /D "Z7_SFX" /D "Z7_NO_CRYPTO" /Yu"StdAfx.h" /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x419 /d "NDEBUG" @@ -71,7 +71,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /Gz /MTd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "NO_REGISTRY" /D "_SFX" /D "_NO_CRYPTO" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "Z7_EXTRACT_ONLY" /D "Z7_NO_REGISTRY" /D "Z7_SFX" /D "Z7_NO_CRYPTO" /Yu"StdAfx.h" /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x419 /d "_DEBUG" @@ -97,8 +97,8 @@ LINK32=link.exe # PROP Intermediate_Dir "ReleaseD" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" -# ADD BASE CPP /nologo /MD /W3 /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "_SFX" /Yu"StdAfx.h" /FD /c -# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "NO_REGISTRY" /D "_SFX" /D "_NO_CRYPTO" /Yu"StdAfx.h" /FD /c +# ADD BASE CPP /nologo /MD /W3 /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "Z7_EXTRACT_ONLY" /D "Z7_NO_REGISTRY" /D "Z7_SFX" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "Z7_EXTRACT_ONLY" /D "Z7_NO_REGISTRY" /D "Z7_SFX" /D "Z7_NO_CRYPTO" /Yu"StdAfx.h" /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x419 /d "NDEBUG" @@ -221,6 +221,10 @@ SOURCE=..\..\Compress\Bcj2Coder.cpp # End Source File # Begin Source File +SOURCE=..\..\Compress\Bcj2Coder.h +# End Source File +# Begin Source File + SOURCE=..\..\Compress\Bcj2Register.cpp # End Source File # Begin Source File @@ -229,6 +233,10 @@ SOURCE=..\..\Compress\BcjCoder.cpp # End Source File # Begin Source File +SOURCE=..\..\Compress\BcjCoder.h +# End Source File +# Begin Source File + SOURCE=..\..\Compress\BcjRegister.cpp # End Source File # Begin Source File @@ -249,6 +257,10 @@ SOURCE=..\..\Compress\CopyCoder.cpp # End Source File # Begin Source File +SOURCE=..\..\Compress\CopyCoder.h +# End Source File +# Begin Source File + SOURCE=..\..\Compress\CopyRegister.cpp # End Source File # Begin Source File @@ -289,6 +301,10 @@ SOURCE=..\..\..\Common\CommandLineParser.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\Common.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\CRC.cpp # End Source File # Begin Source File @@ -305,6 +321,10 @@ SOURCE=..\..\..\Common\IntToString.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\MyCom.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\MyString.cpp # End Source File # Begin Source File @@ -449,6 +469,14 @@ SOURCE=..\..\..\Windows\Synchronization.h # End Source File # Begin Source File +SOURCE=..\..\..\Windows\System.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\System.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Windows\Window.cpp # End Source File # Begin Source File @@ -456,7 +484,7 @@ SOURCE=..\..\..\Windows\Window.cpp SOURCE=..\..\..\Windows\Window.h # End Source File # End Group -# Begin Group "7z Common" +# Begin Group "7zip Common" # PROP Default_Filter "" # Begin Source File @@ -469,6 +497,14 @@ SOURCE=..\..\Common\CreateCoder.h # End Source File # Begin Source File +SOURCE=..\..\Common\CWrappers.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\CWrappers.h +# End Source File +# Begin Source File + SOURCE=..\..\Common\FileStreams.cpp # End Source File # Begin Source File @@ -651,6 +687,19 @@ SOURCE=..\..\..\..\C\7zCrcOpt.c # End Source File # Begin Source File +SOURCE=..\..\..\..\C\7zStream.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zTypes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zWindows.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\Alloc.c # SUBTRACT CPP /YX /Yc /Yu # End Source File @@ -688,6 +737,10 @@ SOURCE=..\..\..\..\C\BraIA64.c # End Source File # Begin Source File +SOURCE=..\..\..\..\C\Compiler.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\CpuArch.c # SUBTRACT CPP /YX /Yc /Yu # End Source File @@ -724,6 +777,15 @@ SOURCE=..\..\..\..\C\Lzma2Dec.h # End Source File # Begin Source File +SOURCE=..\..\..\..\C\Lzma2DecMt.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2DecMt.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\LzmaDec.c # SUBTRACT CPP /YX /Yc /Yu # End Source File @@ -733,6 +795,15 @@ SOURCE=..\..\..\..\C\LzmaDec.h # End Source File # Begin Source File +SOURCE=..\..\..\..\C\MtDec.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\MtDec.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\Threads.c # SUBTRACT CPP /YX /Yc /Yu # End Source File @@ -741,6 +812,30 @@ SOURCE=..\..\..\..\C\Threads.c SOURCE=..\..\..\..\C\Threads.h # End Source File # End Group +# Begin Group "7zip" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\IArchive.h +# End Source File +# Begin Source File + +SOURCE=..\..\ICoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\IDecl.h +# End Source File +# Begin Source File + +SOURCE=..\..\IPassword.h +# End Source File +# Begin Source File + +SOURCE=..\..\IProgress.h +# End Source File +# End Group # Begin Source File SOURCE=.\ExtractCallbackSfx.cpp diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp index aef2e1969c9..47d7966d771 100644 --- a/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp +++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp @@ -2,8 +2,9 @@ #include "StdAfx.h" -#include "../../../Common/MyWindows.h" +#include "../../../../C/DllSecur.h" +#include "../../../Common/MyWindows.h" #include "../../../Common/MyInitGuid.h" #include "../../../Common/CommandLineParser.h" @@ -23,19 +24,19 @@ #include "ExtractEngine.h" -#include "../../../../C/DllSecur.h" - #include "resource.h" using namespace NWindows; using namespace NFile; using namespace NDir; +extern +HINSTANCE g_hInstance; HINSTANCE g_hInstance; -static CFSTR kTempDirPrefix = FTEXT("7zS"); +static CFSTR const kTempDirPrefix = FTEXT("7zS"); -#define _SHELL_EXECUTE +#define MY_SHELL_EXECUTE static bool ReadDataString(CFSTR fileName, LPCSTR startID, LPCSTR endID, AString &stringResult) @@ -44,44 +45,44 @@ static bool ReadDataString(CFSTR fileName, LPCSTR startID, NIO::CInFile inFile; if (!inFile.Open(fileName)) return false; - const int kBufferSize = (1 << 12); + const size_t kBufferSize = (1 << 12); Byte buffer[kBufferSize]; - int signatureStartSize = MyStringLen(startID); - int signatureEndSize = MyStringLen(endID); + const unsigned signatureStartSize = MyStringLen(startID); + const unsigned signatureEndSize = MyStringLen(endID); - UInt32 numBytesPrev = 0; + size_t numBytesPrev = 0; bool writeMode = false; UInt64 posTotal = 0; for (;;) { if (posTotal > (1 << 20)) return (stringResult.IsEmpty()); - UInt32 numReadBytes = kBufferSize - numBytesPrev; - UInt32 processedSize; - if (!inFile.Read(buffer + numBytesPrev, numReadBytes, processedSize)) + const size_t numReadBytes = kBufferSize - numBytesPrev; + size_t processedSize; + if (!inFile.ReadFull(buffer + numBytesPrev, numReadBytes, processedSize)) return false; if (processedSize == 0) return true; - UInt32 numBytesInBuffer = numBytesPrev + processedSize; + const size_t numBytesInBuffer = numBytesPrev + processedSize; UInt32 pos = 0; for (;;) { if (writeMode) { - if (pos > numBytesInBuffer - signatureEndSize) + if (pos + signatureEndSize > numBytesInBuffer) break; if (memcmp(buffer + pos, endID, signatureEndSize) == 0) return true; - char b = buffer[pos]; + const Byte b = buffer[pos]; if (b == 0) return false; - stringResult += b; + stringResult += (char)b; pos++; } else { - if (pos > numBytesInBuffer - signatureStartSize) + if (pos + signatureStartSize > numBytesInBuffer) break; if (memcmp(buffer + pos, startID, signatureStartSize) == 0) { @@ -101,26 +102,28 @@ static bool ReadDataString(CFSTR fileName, LPCSTR startID, static char kStartID[] = { ',','!','@','I','n','s','t','a','l','l','@','!','U','T','F','-','8','!', 0 }; static char kEndID[] = { ',','!','@','I','n','s','t','a','l','l','E','n','d','@','!', 0 }; -struct CInstallIDInit +static struct CInstallIDInit { CInstallIDInit() { kStartID[0] = ';'; kEndID[0] = ';'; - }; + } } g_CInstallIDInit; +#if defined(_WIN32) && defined(_UNICODE) && !defined(_WIN64) && !defined(UNDER_CE) #define NT_CHECK_FAIL_ACTION ShowErrorMessage(L"Unsupported Windows version"); return 1; +#endif static void ShowErrorMessageSpec(const UString &name) { UString message = NError::MyFormatMessage(::GetLastError()); - int pos = message.Find(L"%1"); + const int pos = message.Find(L"%1"); if (pos >= 0) { - message.Delete(pos, 2); - message.Insert(pos, name); + message.Delete((unsigned)pos, 2); + message.Insert((unsigned)pos, name); } ShowErrorMessage(NULL, message); } @@ -144,7 +147,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, // InitCommonControls(); UString archiveName, switches; - #ifdef _SHELL_EXECUTE + #ifdef MY_SHELL_EXECUTE UString executeFile, executeParameters; #endif NCommandLineParser::SplitCommandLine(GetCommandLineW(), archiveName, switches); @@ -169,7 +172,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, return 1; } - UString dirPrefix = L"." WSTRING_PATH_SEPARATOR; + UString dirPrefix ("." STRING_PATH_SEPARATOR); UString appLaunched; bool showProgress = true; if (!config.IsEmpty()) @@ -181,25 +184,25 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, ShowErrorMessage(L"Config failed"); return 1; } - UString friendlyName = GetTextConfigValue(pairs, L"Title"); - UString installPrompt = GetTextConfigValue(pairs, L"BeginPrompt"); - UString progress = GetTextConfigValue(pairs, L"Progress"); + const UString friendlyName = GetTextConfigValue(pairs, "Title"); + const UString installPrompt = GetTextConfigValue(pairs, "BeginPrompt"); + const UString progress = GetTextConfigValue(pairs, "Progress"); if (progress.IsEqualTo_Ascii_NoCase("no")) showProgress = false; - int index = FindTextConfigItem(pairs, L"Directory"); + const int index = FindTextConfigItem(pairs, "Directory"); if (index >= 0) dirPrefix = pairs[index].String; if (!installPrompt.IsEmpty() && !assumeYes) { - if (MessageBoxW(0, installPrompt, friendlyName, MB_YESNO | + if (MessageBoxW(NULL, installPrompt, friendlyName, MB_YESNO | MB_ICONQUESTION) != IDYES) return 0; } - appLaunched = GetTextConfigValue(pairs, L"RunProgram"); + appLaunched = GetTextConfigValue(pairs, "RunProgram"); - #ifdef _SHELL_EXECUTE - executeFile = GetTextConfigValue(pairs, L"ExecuteFile"); - executeParameters = GetTextConfigValue(pairs, L"ExecuteParameters"); + #ifdef MY_SHELL_EXECUTE + executeFile = GetTextConfigValue(pairs, "ExecuteFile"); + executeParameters = GetTextConfigValue(pairs, "ExecuteParameters"); #endif } @@ -207,17 +210,17 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, if (!tempDir.Create(kTempDirPrefix)) { if (!assumeYes) - ShowErrorMessage(L"Can not create temp folder archive"); + ShowErrorMessage(L"Cannot create temp folder archive"); return 1; } CCodecs *codecs = new CCodecs; CMyComPtr<IUnknown> compressCodecsInfo = codecs; { - HRESULT result = codecs->Load(); + const HRESULT result = codecs->Load(); if (result != S_OK) { - ShowErrorMessage(L"Can not load codecs"); + ShowErrorMessage(L"Cannot load codecs"); return 1; } } @@ -243,7 +246,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, { if (errorMessage.IsEmpty()) errorMessage = NError::MyFormatMessage(result); - ::MessageBoxW(0, errorMessage, NWindows::MyLoadString(IDS_EXTRACTION_ERROR_TITLE), MB_ICONERROR); + ::MessageBoxW(NULL, errorMessage, NWindows::MyLoadString(IDS_EXTRACTION_ERROR_TITLE), MB_ICONERROR); } } return 1; @@ -256,11 +259,11 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, return 1; #endif - HANDLE hProcess = 0; -#ifdef _SHELL_EXECUTE + HANDLE hProcess = NULL; +#ifdef MY_SHELL_EXECUTE if (!executeFile.IsEmpty()) { - CSysString filePath = GetSystemString(executeFile); + CSysString filePath (GetSystemString(executeFile)); SHELLEXECUTEINFO execInfo; execInfo.cbSize = sizeof(execInfo); execInfo.fMask = SEE_MASK_NOCLOSEPROCESS @@ -278,7 +281,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, executeParameters += switches; } - CSysString parametersSys = GetSystemString(executeParameters); + const CSysString parametersSys (GetSystemString(executeParameters)); if (parametersSys.IsEmpty()) execInfo.lpParameters = NULL; else @@ -286,13 +289,13 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, execInfo.lpDirectory = NULL; execInfo.nShow = SW_SHOWNORMAL; - execInfo.hProcess = 0; + execInfo.hProcess = NULL; /* BOOL success = */ ::ShellExecuteEx(&execInfo); UINT32 result = (UINT32)(UINT_PTR)execInfo.hInstApp; if (result <= 32) { if (!assumeYes) - ShowErrorMessage(L"Can not open file"); + ShowErrorMessage(L"Cannot open file"); return 1; } hProcess = execInfo.hProcess; @@ -303,10 +306,10 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, if (appLaunched.IsEmpty()) { appLaunched = L"setup.exe"; - if (!NFind::DoesFileExist(us2fs(appLaunched))) + if (!NFind::DoesFileExist_FollowLink(us2fs(appLaunched))) { if (!assumeYes) - ShowErrorMessage(L"Can not find setup.exe"); + ShowErrorMessage(L"Cannot find setup.exe"); return 1; } } @@ -317,7 +320,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, appLaunched.Replace(L"%%T" WSTRING_PATH_SEPARATOR, fs2us(s2)); } - UString appNameForError = appLaunched; // actually we need to rtemove parameters also + const UString appNameForError = appLaunched; // actually we need to rtemove parameters also appLaunched.Replace(L"%%T", fs2us(tempDirPath)); @@ -328,20 +331,21 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, } STARTUPINFO startupInfo; startupInfo.cb = sizeof(startupInfo); - startupInfo.lpReserved = 0; - startupInfo.lpDesktop = 0; - startupInfo.lpTitle = 0; + startupInfo.lpReserved = NULL; + startupInfo.lpDesktop = NULL; + startupInfo.lpTitle = NULL; startupInfo.dwFlags = 0; startupInfo.cbReserved2 = 0; - startupInfo.lpReserved2 = 0; + startupInfo.lpReserved2 = NULL; PROCESS_INFORMATION processInformation; - CSysString appLaunchedSys = GetSystemString(dirPrefix + appLaunched); + const CSysString appLaunchedSys (GetSystemString(dirPrefix + appLaunched)); - BOOL createResult = CreateProcess(NULL, (LPTSTR)(LPCTSTR)appLaunchedSys, - NULL, NULL, FALSE, 0, NULL, NULL /*tempDir.GetPath() */, - &startupInfo, &processInformation); + const BOOL createResult = CreateProcess(NULL, + appLaunchedSys.Ptr_non_const(), + NULL, NULL, FALSE, 0, NULL, NULL /*tempDir.GetPath() */, + &startupInfo, &processInformation); if (createResult == 0) { if (!assumeYes) @@ -355,7 +359,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, ::CloseHandle(processInformation.hThread); hProcess = processInformation.hProcess; } - if (hProcess != 0) + if (hProcess) { WaitForSingleObject(hProcess, INFINITE); ::CloseHandle(hProcess); diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/StdAfx.h b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/StdAfx.h index 37bbd0c33b7..4f27255c6a2 100644 --- a/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/StdAfx.h +++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/StdAfx.h @@ -1,13 +1,6 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H - -#include "../../../Common/Common.h" - -#include <commctrl.h> - -// #define printf(x) NO_PRINTF_(x) -// #define sprintf(x) NO_SPRINTF_(x) - +#if _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' #endif +#include "../../UI/FileManager/StdAfx.h" diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/makefile b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/makefile index 5849cf36907..ea0ece23a79 100644 --- a/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/makefile +++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXSetup/makefile @@ -1,10 +1,12 @@ PROG = 7zS.sfx +MY_FIXED = 1 + CFLAGS = $(CFLAGS) \ - -DNO_REGISTRY \ - -DEXTRACT_ONLY \ - -DNO_READ_FROM_CODER \ - -D_SFX \ - -D_NO_CRYPTO \ + -DZ7_NO_REGISTRY \ + -DZ7_EXTRACT_ONLY \ + -DZ7_NO_READ_FROM_CODER \ + -DZ7_SFX \ + -DZ7_NO_CRYPTO \ CURRENT_OBJS = \ $O\SfxSetup.obj \ @@ -33,6 +35,7 @@ WIN_OBJS = \ $O\PropVariant.obj \ $O\ResourceString.obj \ $O\Synchronization.obj \ + $O\System.obj \ $O\Window.obj \ WIN_CTRL_OBJS = \ @@ -40,6 +43,7 @@ WIN_CTRL_OBJS = \ 7ZIP_COMMON_OBJS = \ $O\CreateCoder.obj \ + $O\CWrappers.obj \ $O\FileStreams.obj \ $O\InBuffer.obj \ $O\FilterCoder.obj \ @@ -93,6 +97,7 @@ COMPRESS_OBJS = \ $O\LzmaRegister.obj \ C_OBJS = \ + $O\7zStream.obj \ $O\Alloc.obj \ $O\Bcj2.obj \ $O\Bra.obj \ @@ -102,9 +107,12 @@ C_OBJS = \ $O\Delta.obj \ $O\DllSecur.obj \ $O\Lzma2Dec.obj \ + $O\Lzma2DecMt.obj \ $O\LzmaDec.obj \ + $O\MtDec.obj \ $O\Threads.obj \ !include "../../Crc.mak" +!include "../../LzmaDec.mak" !include "../../7zip.mak" diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/SFXWin.dsp b/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/SFXWin.dsp index 301a6c5c756..65cf0bf0b2a 100644 --- a/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/SFXWin.dsp +++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/SFXWin.dsp @@ -44,7 +44,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "_SFXWIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "NO_REGISTRY" /D "NO_READ_FROM_CODER" /D "_SFX" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "Z7_EXTRACT_ONLY" /D "Z7_NO_REGISTRY" /D "Z7_NO_READ_FROM_CODER" /D "Z7_SFX" /Yu"StdAfx.h" /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x419 /d "NDEBUG" @@ -71,7 +71,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /Gz /MTd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "_SFXWIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "NO_REGISTRY" /D "NO_READ_FROM_CODER" /D "_SFX" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "Z7_EXTRACT_ONLY" /D "Z7_NO_REGISTRY" /D "Z7_NO_READ_FROM_CODER" /D "Z7_SFX" /Yu"StdAfx.h" /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x419 /d "_DEBUG" @@ -97,8 +97,8 @@ LINK32=link.exe # PROP Intermediate_Dir "SFXWin___Win32_ReleaseD" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" -# ADD BASE CPP /nologo /Gz /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "_SFX" /Yu"StdAfx.h" /FD /c -# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "_SFXWIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "NO_REGISTRY" /D "NO_READ_FROM_CODER" /D "_SFX" /Yu"StdAfx.h" /FD /c +# ADD BASE CPP /nologo /Gz /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "Z7_EXTRACT_ONLY" /D "Z7_NO_REGISTRY" /D "Z7_SFX" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "Z7_EXTRACT_ONLY" /D "Z7_NO_REGISTRY" /D "Z7_NO_READ_FROM_CODER" /D "Z7_SFX" /Yu"StdAfx.h" /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x419 /d "NDEBUG" @@ -221,6 +221,10 @@ SOURCE=..\..\Compress\Bcj2Coder.cpp # End Source File # Begin Source File +SOURCE=..\..\Compress\Bcj2Coder.h +# End Source File +# Begin Source File + SOURCE=..\..\Compress\Bcj2Register.cpp # End Source File # Begin Source File @@ -229,6 +233,10 @@ SOURCE=..\..\Compress\BcjCoder.cpp # End Source File # Begin Source File +SOURCE=..\..\Compress\BcjCoder.h +# End Source File +# Begin Source File + SOURCE=..\..\Compress\BcjRegister.cpp # End Source File # Begin Source File @@ -249,6 +257,10 @@ SOURCE=..\..\Compress\CopyCoder.cpp # End Source File # Begin Source File +SOURCE=..\..\Compress\CopyCoder.h +# End Source File +# Begin Source File + SOURCE=..\..\Compress\CopyRegister.cpp # End Source File # Begin Source File @@ -277,6 +289,10 @@ SOURCE=..\..\Compress\PpmdDecoder.cpp # End Source File # Begin Source File +SOURCE=..\..\Compress\PpmdDecoder.h +# End Source File +# Begin Source File + SOURCE=..\..\Compress\PpmdRegister.cpp # End Source File # End Group @@ -537,6 +553,14 @@ SOURCE=..\..\..\Windows\Control\ListView.h # End Group # Begin Source File +SOURCE=..\..\..\Windows\Clipboard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Clipboard.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Windows\CommonDialog.cpp # End Source File # Begin Source File @@ -593,6 +617,14 @@ SOURCE=..\..\..\Windows\FileName.h # End Source File # Begin Source File +SOURCE=..\..\..\Windows\MemoryGlobal.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryGlobal.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Windows\PropVariant.cpp # End Source File # Begin Source File @@ -633,6 +665,14 @@ SOURCE=..\..\..\Windows\Synchronization.h # End Source File # Begin Source File +SOURCE=..\..\..\Windows\System.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\System.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Windows\Window.cpp # End Source File # Begin Source File @@ -653,6 +693,10 @@ SOURCE=..\..\..\Common\CommandLineParser.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\Common.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\CRC.cpp # End Source File # Begin Source File @@ -693,6 +737,10 @@ SOURCE=..\..\..\Common\NewHandler.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\Sha256Prepare.cpp +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\StringConvert.cpp # End Source File # Begin Source File @@ -823,6 +871,15 @@ SOURCE=..\..\..\..\C\7zCrcOpt.c # End Source File # Begin Source File +SOURCE=..\..\..\..\C\7zStream.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zWindows.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\Aes.c # SUBTRACT CPP /YX /Yc /Yu # End Source File @@ -874,6 +931,10 @@ SOURCE=..\..\..\..\C\BraIA64.c # End Source File # Begin Source File +SOURCE=..\..\..\..\C\Compiler.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\CpuArch.c # SUBTRACT CPP /YX /Yc /Yu # End Source File @@ -906,6 +967,15 @@ SOURCE=..\..\..\..\C\Lzma2Dec.h # End Source File # Begin Source File +SOURCE=..\..\..\..\C\Lzma2DecMt.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2DecMt.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\LzmaDec.c # SUBTRACT CPP /YX /Yc /Yu # End Source File @@ -915,6 +985,15 @@ SOURCE=..\..\..\..\C\LzmaDec.h # End Source File # Begin Source File +SOURCE=..\..\..\..\C\MtDec.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\MtDec.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\Ppmd7.c # SUBTRACT CPP /YX /Yc /Yu # End Source File @@ -934,6 +1013,11 @@ SOURCE=..\..\..\..\C\Sha256.c # End Source File # Begin Source File +SOURCE=..\..\..\..\C\Sha256Opt.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\Threads.c # SUBTRACT CPP /YX /Yc /Yu # End Source File @@ -942,13 +1026,33 @@ SOURCE=..\..\..\..\C\Threads.c SOURCE=..\..\..\..\C\Threads.h # End Source File # End Group +# Begin Group "7zip" + +# PROP Default_Filter "" # Begin Source File -SOURCE=.\7z.ico +SOURCE=..\..\Archive\IArchive.h +# End Source File +# Begin Source File + +SOURCE=..\..\ICoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\IDecl.h +# End Source File +# Begin Source File + +SOURCE=..\..\IPassword.h # End Source File # Begin Source File -SOURCE=.\7z1.ico +SOURCE=..\..\IProgress.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\7z.ico # End Source File # Begin Source File diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/SfxWin.cpp b/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/SfxWin.cpp index db7acfef7c8..3e1880edffa 100644 --- a/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/SfxWin.cpp +++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/SfxWin.cpp @@ -4,7 +4,13 @@ #include "../../../Common/MyWindows.h" +#if defined(__MINGW32__) || defined(__MINGW64__) +#include <shlwapi.h> +#else #include <Shlwapi.h> +#endif + +#include "../../../../C/DllSecur.h" #include "../../../Common/MyInitGuid.h" @@ -28,33 +34,36 @@ #include "../../UI/GUI/ExtractGUI.h" #include "../../UI/GUI/ExtractRes.h" -#include "../../../../C/DllSecur.h" - using namespace NWindows; using namespace NFile; using namespace NDir; +extern +HINSTANCE g_hInstance; HINSTANCE g_hInstance; #ifndef UNDER_CE +static DWORD g_ComCtl32Version; static DWORD GetDllVersion(LPCTSTR dllName) { DWORD dwVersion = 0; - HINSTANCE hinstDll = LoadLibrary(dllName); + const HINSTANCE hinstDll = LoadLibrary(dllName); if (hinstDll) { - DLLGETVERSIONPROC pDllGetVersion = (DLLGETVERSIONPROC)GetProcAddress(hinstDll, "DllGetVersion"); - if (pDllGetVersion) + const + DLLGETVERSIONPROC func_DllGetVersion = Z7_GET_PROC_ADDRESS( + DLLGETVERSIONPROC, hinstDll, "DllGetVersion"); + if (func_DllGetVersion) { DLLVERSIONINFO dvi; ZeroMemory(&dvi, sizeof(dvi)); dvi.cbSize = sizeof(dvi); - HRESULT hr = (*pDllGetVersion)(&dvi); + const HRESULT hr = func_DllGetVersion(&dvi); if (SUCCEEDED(hr)) - dwVersion = MAKELONG(dvi.dwMinorVersion, dvi.dwMajorVersion); + dwVersion = (DWORD)MAKELONG(dvi.dwMinorVersion, dvi.dwMajorVersion); } FreeLibrary(hinstDll); } @@ -63,16 +72,18 @@ static DWORD GetDllVersion(LPCTSTR dllName) #endif +extern +bool g_LVN_ITEMACTIVATE_Support; bool g_LVN_ITEMACTIVATE_Support = true; -static const wchar_t *kUnknownExceptionMessage = L"ERROR: Unknown Error!"; +static const wchar_t * const kUnknownExceptionMessage = L"ERROR: Unknown Error!"; -void ErrorMessageForHRESULT(HRESULT res) +static void ErrorMessageForHRESULT(HRESULT res) { ShowErrorMessage(HResultToMessage(res)); } -int APIENTRY WinMain2() +static int APIENTRY WinMain2() { // OleInitialize is required for ProgressBar in TaskBar. #ifndef UNDER_CE @@ -101,7 +112,7 @@ int APIENTRY WinMain2() const UString &s = commandStrings[i]; if (s.Len() > 1 && s[0] == '-') { - wchar_t c = MyCharLower_Ascii(s[1]); + const wchar_t c = MyCharLower_Ascii(s[1]); if (c == 'y') { assumeYes = true; @@ -152,7 +163,7 @@ int APIENTRY WinMain2() CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs; ecs->Init(); - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO ecs->PasswordIsDefined = !password.IsEmpty(); ecs->Password = password; #endif @@ -178,7 +189,7 @@ int APIENTRY WinMain2() v1.Add(fs2us(fullPath)); v2.Add(fs2us(fullPath)); NWildcard::CCensorNode wildcardCensor; - wildcardCensor.AddItem(true, L"*", true, true, true, true); + wildcardCensor.Add_Wildcard(); bool messageWasDisplayed = false; result = ExtractGUI(codecs, @@ -206,7 +217,9 @@ int APIENTRY WinMain2() return NExitCode::kFatalError; } +#if defined(_WIN32) && defined(_UNICODE) && !defined(_WIN64) && !defined(UNDER_CE) #define NT_CHECK_FAIL_ACTION ShowErrorMessage(L"Unsupported Windows version"); return NExitCode::kFatalError; +#endif int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, #ifdef UNDER_CE diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/StdAfx.h b/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/StdAfx.h index 975a17e8bf7..4f27255c6a2 100644 --- a/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/StdAfx.h +++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/StdAfx.h @@ -1,14 +1,6 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H - -#include "../../../Common/Common.h" - -#include <commctrl.h> -#include <ShlObj.h> - -// #define printf(x) NO_PRINTF_(x) -// #define sprintf(x) NO_SPRINTF_(x) - +#if _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' #endif +#include "../../UI/FileManager/StdAfx.h" diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/makefile b/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/makefile index dc48ae88a78..69a8553cf61 100644 --- a/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/makefile +++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/makefile @@ -1,9 +1,11 @@ PROG = 7z.sfx +MY_FIXED = 1 + CFLAGS = $(CFLAGS) \ - -DNO_REGISTRY \ - -DEXTRACT_ONLY \ - -DNO_READ_FROM_CODER \ - -D_SFX \ + -DZ7_NO_REGISTRY \ + -DZ7_EXTRACT_ONLY \ + -DZ7_NO_READ_FROM_CODER \ + -DZ7_SFX \ !IFDEF UNDER_CE LIBS = $(LIBS) ceshell.lib Commctrl.lib @@ -29,6 +31,7 @@ COMMON_OBJS = \ $O\Wildcard.obj \ WIN_OBJS = \ + $O\Clipboard.obj \ $O\CommonDialog.obj \ $O\DLL.obj \ $O\ErrorMsg.obj \ @@ -36,11 +39,13 @@ WIN_OBJS = \ $O\FileFind.obj \ $O\FileIO.obj \ $O\FileName.obj \ + $O\MemoryGlobal.obj \ $O\PropVariant.obj \ $O\PropVariantConv.obj \ $O\ResourceString.obj \ $O\Shell.obj \ $O\Synchronization.obj \ + $O\System.obj \ $O\Window.obj \ WIN_CTRL_OBJS = \ @@ -126,6 +131,7 @@ CRYPTO_OBJS = \ $O\MyAes.obj \ C_OBJS = \ + $O\7zStream.obj \ $O\Alloc.obj \ $O\Bcj2.obj \ $O\Bra.obj \ @@ -135,13 +141,16 @@ C_OBJS = \ $O\Delta.obj \ $O\DllSecur.obj \ $O\Lzma2Dec.obj \ + $O\Lzma2DecMt.obj \ $O\LzmaDec.obj \ + $O\MtDec.obj \ $O\Ppmd7.obj \ $O\Ppmd7Dec.obj \ - $O\Sha256.obj \ $O\Threads.obj \ !include "../../Aes.mak" !include "../../Crc.mak" +!include "../../LzmaDec.mak" +!include "../../Sha256.mak" !include "../../7zip.mak" diff --git a/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/resource.rc b/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/resource.rc index 91292b2f11a..3b2217a58b6 100644 --- a/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/resource.rc +++ b/3rdparty/lzma/CPP/7zip/Bundles/SFXWin/resource.rc @@ -48,3 +48,8 @@ STRINGTABLE DISCARDABLE BEGIN IDS_PROP_MTIME "Modified" END + + +#ifndef UNDER_CE +1 24 MOVEABLE PURE "../../UI/GUI/7zG.exe.manifest" +#endif diff --git a/3rdparty/lzma/CPP/7zip/Common/CWrappers.cpp b/3rdparty/lzma/CPP/7zip/Common/CWrappers.cpp index a77b67e8664..346774e5d04 100644 --- a/3rdparty/lzma/CPP/7zip/Common/CWrappers.cpp +++ b/3rdparty/lzma/CPP/7zip/Common/CWrappers.cpp @@ -1,4 +1,4 @@ -// CWrappers.h +// CWrappers.c #include "StdAfx.h" @@ -8,43 +8,74 @@ #include "StreamUtils.h" +SRes HRESULT_To_SRes(HRESULT res, SRes defaultRes) throw() +{ + switch (res) + { + case S_OK: return SZ_OK; + case E_OUTOFMEMORY: return SZ_ERROR_MEM; + case E_INVALIDARG: return SZ_ERROR_PARAM; + case E_ABORT: return SZ_ERROR_PROGRESS; + case S_FALSE: return SZ_ERROR_DATA; + case E_NOTIMPL: return SZ_ERROR_UNSUPPORTED; + } + return defaultRes; +} + + +HRESULT SResToHRESULT(SRes res) throw() +{ + switch (res) + { + case SZ_OK: return S_OK; + + case SZ_ERROR_DATA: + case SZ_ERROR_CRC: + case SZ_ERROR_INPUT_EOF: + return S_FALSE; + + case SZ_ERROR_MEM: return E_OUTOFMEMORY; + case SZ_ERROR_PARAM: return E_INVALIDARG; + case SZ_ERROR_PROGRESS: return E_ABORT; + case SZ_ERROR_UNSUPPORTED: return E_NOTIMPL; + // case SZ_ERROR_OUTPUT_EOF: + // case SZ_ERROR_READ: + // case SZ_ERROR_WRITE: + // case SZ_ERROR_THREAD: + // case SZ_ERROR_ARCHIVE: + // case SZ_ERROR_NO_ARCHIVE: + // return E_FAIL; + } + if (res < 0) + return res; + return E_FAIL; +} + + #define PROGRESS_UNKNOWN_VALUE ((UInt64)(Int64)-1) #define CONVERT_PR_VAL(x) (x == PROGRESS_UNKNOWN_VALUE ? NULL : &x) -static SRes CompressProgress(void *pp, UInt64 inSize, UInt64 outSize) throw() + +static SRes CompressProgress(ICompressProgressPtr pp, UInt64 inSize, UInt64 outSize) throw() { - CCompressProgressWrap *p = (CCompressProgressWrap *)pp; + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CCompressProgressWrap) p->Res = p->Progress->SetRatioInfo(CONVERT_PR_VAL(inSize), CONVERT_PR_VAL(outSize)); - return (SRes)p->Res; + return HRESULT_To_SRes(p->Res, SZ_ERROR_PROGRESS); } -CCompressProgressWrap::CCompressProgressWrap(ICompressProgressInfo *progress) throw() +void CCompressProgressWrap::Init(ICompressProgressInfo *progress) throw() { - p.Progress = CompressProgress; + vt.Progress = CompressProgress; Progress = progress; Res = SZ_OK; } static const UInt32 kStreamStepSize = (UInt32)1 << 31; -SRes HRESULT_To_SRes(HRESULT res, SRes defaultRes) +static SRes MyRead(ISeqInStreamPtr pp, void *data, size_t *size) throw() { - switch (res) - { - case S_OK: return SZ_OK; - case E_OUTOFMEMORY: return SZ_ERROR_MEM; - case E_INVALIDARG: return SZ_ERROR_PARAM; - case E_ABORT: return SZ_ERROR_PROGRESS; - case S_FALSE: return SZ_ERROR_DATA; - case E_NOTIMPL: return SZ_ERROR_UNSUPPORTED; - } - return defaultRes; -} - -static SRes MyRead(void *object, void *data, size_t *size) throw() -{ - CSeqInStreamWrap *p = (CSeqInStreamWrap *)object; + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CSeqInStreamWrap) UInt32 curSize = ((*size < kStreamStepSize) ? (UInt32)*size : kStreamStepSize); p->Res = (p->Stream->Read(data, curSize, &curSize)); *size = curSize; @@ -54,9 +85,9 @@ static SRes MyRead(void *object, void *data, size_t *size) throw() return HRESULT_To_SRes(p->Res, SZ_ERROR_READ); } -static size_t MyWrite(void *object, const void *data, size_t size) throw() +static size_t MyWrite(ISeqOutStreamPtr pp, const void *data, size_t size) throw() { - CSeqOutStreamWrap *p = (CSeqOutStreamWrap *)object; + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CSeqOutStreamWrap) if (p->Stream) { p->Res = WriteStream(p->Stream, data, size); @@ -69,49 +100,41 @@ static size_t MyWrite(void *object, const void *data, size_t size) throw() return size; } -CSeqInStreamWrap::CSeqInStreamWrap(ISequentialInStream *stream) throw() + +void CSeqInStreamWrap::Init(ISequentialInStream *stream) throw() { - p.Read = MyRead; + vt.Read = MyRead; Stream = stream; Processed = 0; + Res = S_OK; } -CSeqOutStreamWrap::CSeqOutStreamWrap(ISequentialOutStream *stream) throw() +void CSeqOutStreamWrap::Init(ISequentialOutStream *stream) throw() { - p.Write = MyWrite; + vt.Write = MyWrite; Stream = stream; Res = SZ_OK; Processed = 0; } -HRESULT SResToHRESULT(SRes res) throw() -{ - switch (res) - { - case SZ_OK: return S_OK; - case SZ_ERROR_MEM: return E_OUTOFMEMORY; - case SZ_ERROR_PARAM: return E_INVALIDARG; - case SZ_ERROR_PROGRESS: return E_ABORT; - case SZ_ERROR_DATA: return S_FALSE; - case SZ_ERROR_UNSUPPORTED: return E_NOTIMPL; - } - return E_FAIL; -} -static SRes InStreamWrap_Read(void *pp, void *data, size_t *size) throw() +static SRes InStreamWrap_Read(ISeekInStreamPtr pp, void *data, size_t *size) throw() { - CSeekInStreamWrap *p = (CSeekInStreamWrap *)pp; + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CSeekInStreamWrap) UInt32 curSize = ((*size < kStreamStepSize) ? (UInt32)*size : kStreamStepSize); p->Res = p->Stream->Read(data, curSize, &curSize); *size = curSize; return (p->Res == S_OK) ? SZ_OK : SZ_ERROR_READ; } -static SRes InStreamWrap_Seek(void *pp, Int64 *offset, ESzSeek origin) throw() +static SRes InStreamWrap_Seek(ISeekInStreamPtr pp, Int64 *offset, ESzSeek origin) throw() { - CSeekInStreamWrap *p = (CSeekInStreamWrap *)pp; + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CSeekInStreamWrap) UInt32 moveMethod; - switch (origin) + /* we need (int)origin to eliminate the clang warning: + default label in switch which covers all enumeration values + [-Wcovered-switch-default */ + switch ((int)origin) { case SZ_SEEK_SET: moveMethod = STREAM_SEEK_SET; break; case SZ_SEEK_CUR: moveMethod = STREAM_SEEK_CUR; break; @@ -124,11 +147,11 @@ static SRes InStreamWrap_Seek(void *pp, Int64 *offset, ESzSeek origin) throw() return (p->Res == S_OK) ? SZ_OK : SZ_ERROR_READ; } -CSeekInStreamWrap::CSeekInStreamWrap(IInStream *stream) throw() +void CSeekInStreamWrap::Init(IInStream *stream) throw() { Stream = stream; - p.Read = InStreamWrap_Read; - p.Seek = InStreamWrap_Seek; + vt.Read = InStreamWrap_Read; + vt.Seek = InStreamWrap_Seek; Res = S_OK; } @@ -138,27 +161,27 @@ CSeekInStreamWrap::CSeekInStreamWrap(IInStream *stream) throw() void CByteInBufWrap::Free() throw() { ::MidFree(Buf); - Buf = 0; + Buf = NULL; } bool CByteInBufWrap::Alloc(UInt32 size) throw() { - if (Buf == 0 || size != Size) + if (!Buf || size != Size) { Free(); Lim = Cur = Buf = (Byte *)::MidAlloc((size_t)size); Size = size; } - return (Buf != 0); + return (Buf != NULL); } Byte CByteInBufWrap::ReadByteFromNewBlock() throw() { - if (Res == S_OK) + if (!Extra && Res == S_OK) { UInt32 avail; - Processed += (Cur - Buf); Res = Stream->Read(Buf, Size, &avail); + Processed += (size_t)(Cur - Buf); Cur = Buf; Lim = Buf + avail; if (avail != 0) @@ -168,55 +191,106 @@ Byte CByteInBufWrap::ReadByteFromNewBlock() throw() return 0; } -static Byte Wrap_ReadByte(void *pp) throw() +// #pragma GCC diagnostic ignored "-Winvalid-offsetof" + +static Byte Wrap_ReadByte(IByteInPtr pp) throw() { - CByteInBufWrap *p = (CByteInBufWrap *)pp; + CByteInBufWrap *p = Z7_CONTAINER_FROM_VTBL_CLS(pp, CByteInBufWrap, vt); + // Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CByteInBufWrap) if (p->Cur != p->Lim) return *p->Cur++; return p->ReadByteFromNewBlock(); } -CByteInBufWrap::CByteInBufWrap(): Buf(0) +CByteInBufWrap::CByteInBufWrap() throw(): Buf(NULL) +{ + vt.Read = Wrap_ReadByte; +} + + + +/* ---------- CByteOutBufWrap ---------- */ + +/* +void CLookToSequentialWrap::Free() throw() { - p.Read = Wrap_ReadByte; + ::MidFree(BufBase); + BufBase = NULL; } +bool CLookToSequentialWrap::Alloc(UInt32 size) throw() +{ + if (!BufBase || size != Size) + { + Free(); + BufBase = (Byte *)::MidAlloc((size_t)size); + Size = size; + } + return (BufBase != NULL); +} +*/ + +/* +EXTERN_C_BEGIN + +void CLookToSequentialWrap_Look(ILookInSeqStreamPtr pp) +{ + CLookToSequentialWrap *p = (CLookToSequentialWrap *)pp->Obj; + + if (p->Extra || p->Res != S_OK) + return; + { + UInt32 avail; + p->Res = p->Stream->Read(p->BufBase, p->Size, &avail); + p->Processed += avail; + pp->Buf = p->BufBase; + pp->Limit = pp->Buf + avail; + if (avail == 0) + p->Extra = true; + } +} + +EXTERN_C_END +*/ + /* ---------- CByteOutBufWrap ---------- */ void CByteOutBufWrap::Free() throw() { ::MidFree(Buf); - Buf = 0; + Buf = NULL; } bool CByteOutBufWrap::Alloc(size_t size) throw() { - if (Buf == 0 || size != Size) + if (!Buf || size != Size) { Free(); Buf = (Byte *)::MidAlloc(size); Size = size; } - return (Buf != 0); + return (Buf != NULL); } HRESULT CByteOutBufWrap::Flush() throw() { if (Res == S_OK) { - size_t size = (Cur - Buf); + const size_t size = (size_t)(Cur - Buf); Res = WriteStream(Stream, Buf, size); if (Res == S_OK) Processed += size; - Cur = Buf; + // else throw 11; } + Cur = Buf; // reset pointer for later Wrap_WriteByte() return Res; } -static void Wrap_WriteByte(void *pp, Byte b) throw() +static void Wrap_WriteByte(IByteOutPtr pp, Byte b) throw() { - CByteOutBufWrap *p = (CByteOutBufWrap *)pp; + CByteOutBufWrap *p = Z7_CONTAINER_FROM_VTBL_CLS(pp, CByteOutBufWrap, vt); + // Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CByteOutBufWrap) Byte *dest = p->Cur; *dest = b; p->Cur = ++dest; @@ -224,7 +298,57 @@ static void Wrap_WriteByte(void *pp, Byte b) throw() p->Flush(); } -CByteOutBufWrap::CByteOutBufWrap() throw(): Buf(0) +CByteOutBufWrap::CByteOutBufWrap() throw(): Buf(NULL), Size(0) +{ + vt.Write = Wrap_WriteByte; +} + + +/* ---------- CLookOutWrap ---------- */ + +/* +void CLookOutWrap::Free() throw() +{ + ::MidFree(Buf); + Buf = NULL; +} + +bool CLookOutWrap::Alloc(size_t size) throw() +{ + if (!Buf || size != Size) + { + Free(); + Buf = (Byte *)::MidAlloc(size); + Size = size; + } + return (Buf != NULL); +} + +static size_t LookOutWrap_GetOutBuf(ILookOutStreamPtr pp, void **buf) throw() +{ + CLookOutWrap *p = Z7_CONTAINER_FROM_VTBL_CLS(pp, CLookOutWrap, vt); + *buf = p->Buf; + return p->Size; +} + +static size_t LookOutWrap_Write(ILookOutStreamPtr pp, size_t size) throw() +{ + CLookOutWrap *p = Z7_CONTAINER_FROM_VTBL_CLS(pp, CLookOutWrap, vt); + if (p->Res == S_OK && size != 0) + { + p->Res = WriteStream(p->Stream, p->Buf, size); + if (p->Res == S_OK) + { + p->Processed += size; + return size; + } + } + return 0; +} + +CLookOutWrap::CLookOutWrap() throw(): Buf(NULL), Size(0) { - p.Write = Wrap_WriteByte; + vt.GetOutBuf = LookOutWrap_GetOutBuf; + vt.Write = LookOutWrap_Write; } +*/ diff --git a/3rdparty/lzma/CPP/7zip/Common/CWrappers.h b/3rdparty/lzma/CPP/7zip/Common/CWrappers.h index acadc170edc..6c10a5c2562 100644 --- a/3rdparty/lzma/CPP/7zip/Common/CWrappers.h +++ b/3rdparty/lzma/CPP/7zip/Common/CWrappers.h @@ -1,54 +1,59 @@ // CWrappers.h -#ifndef __C_WRAPPERS_H -#define __C_WRAPPERS_H +#ifndef ZIP7_INC_C_WRAPPERS_H +#define ZIP7_INC_C_WRAPPERS_H #include "../ICoder.h" #include "../../Common/MyCom.h" +SRes HRESULT_To_SRes(HRESULT res, SRes defaultRes) throw(); +HRESULT SResToHRESULT(SRes res) throw(); + struct CCompressProgressWrap { - ICompressProgress p; + ICompressProgress vt; ICompressProgressInfo *Progress; HRESULT Res; - CCompressProgressWrap(ICompressProgressInfo *progress) throw(); + void Init(ICompressProgressInfo *progress) throw(); }; + struct CSeqInStreamWrap { - ISeqInStream p; + ISeqInStream vt; ISequentialInStream *Stream; HRESULT Res; UInt64 Processed; - CSeqInStreamWrap(ISequentialInStream *stream) throw(); + void Init(ISequentialInStream *stream) throw(); }; + struct CSeekInStreamWrap { - ISeekInStream p; + ISeekInStream vt; IInStream *Stream; HRESULT Res; - CSeekInStreamWrap(IInStream *stream) throw(); + void Init(IInStream *stream) throw(); }; + struct CSeqOutStreamWrap { - ISeqOutStream p; + ISeqOutStream vt; ISequentialOutStream *Stream; HRESULT Res; UInt64 Processed; - CSeqOutStreamWrap(ISequentialOutStream *stream) throw(); + void Init(ISequentialOutStream *stream) throw(); }; -HRESULT SResToHRESULT(SRes res) throw(); struct CByteInBufWrap { - IByteIn p; + IByteIn vt; const Byte *Cur; const Byte *Lim; Byte *Buf; @@ -58,7 +63,7 @@ struct CByteInBufWrap bool Extra; HRESULT Res; - CByteInBufWrap(); + CByteInBufWrap() throw(); ~CByteInBufWrap() { Free(); } void Free() throw(); bool Alloc(UInt32 size) throw(); @@ -69,7 +74,40 @@ struct CByteInBufWrap Extra = false; Res = S_OK; } - UInt64 GetProcessed() const { return Processed + (Cur - Buf); } + UInt64 GetProcessed() const { return Processed + (size_t)(Cur - Buf); } + Byte ReadByteFromNewBlock() throw(); + Byte ReadByte() + { + if (Cur != Lim) + return *Cur++; + return ReadByteFromNewBlock(); + } +}; + + +/* +struct CLookToSequentialWrap +{ + Byte *BufBase; + UInt32 Size; + ISequentialInStream *Stream; + UInt64 Processed; + bool Extra; + HRESULT Res; + + CLookToSequentialWrap(): BufBase(NULL) {} + ~CLookToSequentialWrap() { Free(); } + void Free() throw(); + bool Alloc(UInt32 size) throw(); + void Init() + { + // Lim = Cur = Buf; + Processed = 0; + Extra = false; + Res = S_OK; + } + // UInt64 GetProcessed() const { return Processed + (Cur - Buf); } + Byte ReadByteFromNewBlock() throw(); Byte ReadByte() { @@ -79,9 +117,16 @@ struct CByteInBufWrap } }; +EXTERN_C_BEGIN +// void CLookToSequentialWrap_Look(ILookInSeqStream *pp); +EXTERN_C_END +*/ + + + struct CByteOutBufWrap { - IByteOut p; + IByteOut vt; Byte *Cur; const Byte *Lim; Byte *Buf; @@ -101,7 +146,7 @@ struct CByteOutBufWrap Processed = 0; Res = S_OK; } - UInt64 GetProcessed() const { return Processed + (Cur - Buf); } + UInt64 GetProcessed() const { return Processed + (size_t)(Cur - Buf); } HRESULT Flush() throw(); void WriteByte(Byte b) { @@ -111,4 +156,27 @@ struct CByteOutBufWrap } }; + +/* +struct CLookOutWrap +{ + ILookOutStream vt; + Byte *Buf; + size_t Size; + ISequentialOutStream *Stream; + UInt64 Processed; + HRESULT Res; + + CLookOutWrap() throw(); + ~CLookOutWrap() { Free(); } + void Free() throw(); + bool Alloc(size_t size) throw(); + void Init() + { + Processed = 0; + Res = S_OK; + } +}; +*/ + #endif diff --git a/3rdparty/lzma/CPP/7zip/Common/CreateCoder.cpp b/3rdparty/lzma/CPP/7zip/Common/CreateCoder.cpp index 75074ad891f..bf7b04e441c 100644 --- a/3rdparty/lzma/CPP/7zip/Common/CreateCoder.cpp +++ b/3rdparty/lzma/CPP/7zip/Common/CreateCoder.cpp @@ -11,19 +11,23 @@ #include "RegisterCodec.h" static const unsigned kNumCodecsMax = 64; +extern +unsigned g_NumCodecs; unsigned g_NumCodecs = 0; +extern +const CCodecInfo *g_Codecs[]; const CCodecInfo *g_Codecs[kNumCodecsMax]; // We use g_ExternalCodecs in other stages. +#ifdef Z7_EXTERNAL_CODECS /* -#ifdef EXTERNAL_CODECS extern CExternalCodecs g_ExternalCodecs; #define CHECK_GLOBAL_CODECS \ - if (!__externalCodecs || !__externalCodecs->IsSet()) __externalCodecs = &g_ExternalCodecs; -#endif + if (!_externalCodecs || !_externalCodecs->IsSet()) _externalCodecs = &g_ExternalCodecs; */ - #define CHECK_GLOBAL_CODECS +#endif + void RegisterCodec(const CCodecInfo *codecInfo) throw() { @@ -32,7 +36,11 @@ void RegisterCodec(const CCodecInfo *codecInfo) throw() } static const unsigned kNumHashersMax = 16; +extern +unsigned g_NumHashers; unsigned g_NumHashers = 0; +extern +const CHasherInfo *g_Hashers[]; const CHasherInfo *g_Hashers[kNumHashersMax]; void RegisterHasher(const CHasherInfo *hashInfo) throw() @@ -42,12 +50,12 @@ void RegisterHasher(const CHasherInfo *hashInfo) throw() } -#ifdef EXTERNAL_CODECS +#ifdef Z7_EXTERNAL_CODECS static HRESULT ReadNumberOfStreams(ICompressCodecsInfo *codecsInfo, UInt32 index, PROPID propID, UInt32 &res) { NWindows::NCOM::CPropVariant prop; - RINOK(codecsInfo->GetProperty(index, propID, &prop)); + RINOK(codecsInfo->GetProperty(index, propID, &prop)) if (prop.vt == VT_EMPTY) res = 1; else if (prop.vt == VT_UI4) @@ -60,7 +68,7 @@ static HRESULT ReadNumberOfStreams(ICompressCodecsInfo *codecsInfo, UInt32 index static HRESULT ReadIsAssignedProp(ICompressCodecsInfo *codecsInfo, UInt32 index, PROPID propID, bool &res) { NWindows::NCOM::CPropVariant prop; - RINOK(codecsInfo->GetProperty(index, propID, &prop)); + RINOK(codecsInfo->GetProperty(index, propID, &prop)) if (prop.vt == VT_EMPTY) res = true; else if (prop.vt == VT_BOOL) @@ -81,13 +89,13 @@ HRESULT CExternalCodecs::Load() UString s; UInt32 num; - RINOK(GetCodecs->GetNumMethods(&num)); + RINOK(GetCodecs->GetNumMethods(&num)) for (UInt32 i = 0; i < num; i++) { NWindows::NCOM::CPropVariant prop; - RINOK(GetCodecs->GetProperty(i, NMethodPropID::kID, &prop)); + RINOK(GetCodecs->GetProperty(i, NMethodPropID::kID, &prop)) if (prop.vt != VT_UI8) continue; // old Interface info.Id = prop.uhVal.QuadPart; @@ -95,21 +103,22 @@ HRESULT CExternalCodecs::Load() prop.Clear(); info.Name.Empty(); - RINOK(GetCodecs->GetProperty(i, NMethodPropID::kName, &prop)); + RINOK(GetCodecs->GetProperty(i, NMethodPropID::kName, &prop)) if (prop.vt == VT_BSTR) info.Name.SetFromWStr_if_Ascii(prop.bstrVal); else if (prop.vt != VT_EMPTY) continue; - RINOK(ReadNumberOfStreams(GetCodecs, i, NMethodPropID::kPackStreams, info.NumStreams)); + RINOK(ReadNumberOfStreams(GetCodecs, i, NMethodPropID::kPackStreams, info.NumStreams)) { UInt32 numUnpackStreams = 1; - RINOK(ReadNumberOfStreams(GetCodecs, i, NMethodPropID::kUnpackStreams, numUnpackStreams)); + RINOK(ReadNumberOfStreams(GetCodecs, i, NMethodPropID::kUnpackStreams, numUnpackStreams)) if (numUnpackStreams != 1) continue; } - RINOK(ReadIsAssignedProp(GetCodecs, i, NMethodPropID::kEncoderIsAssigned, info.EncoderIsAssigned)); - RINOK(ReadIsAssignedProp(GetCodecs, i, NMethodPropID::kDecoderIsAssigned, info.DecoderIsAssigned)); + RINOK(ReadIsAssignedProp(GetCodecs, i, NMethodPropID::kEncoderIsAssigned, info.EncoderIsAssigned)) + RINOK(ReadIsAssignedProp(GetCodecs, i, NMethodPropID::kDecoderIsAssigned, info.DecoderIsAssigned)) + RINOK(ReadIsAssignedProp(GetCodecs, i, NMethodPropID::kIsFilter, info.IsFilter)) Codecs.Add(info); } @@ -124,7 +133,7 @@ HRESULT CExternalCodecs::Load() { NWindows::NCOM::CPropVariant prop; - RINOK(GetHashers->GetHasherProp(i, NMethodPropID::kID, &prop)); + RINOK(GetHashers->GetHasherProp(i, NMethodPropID::kID, &prop)) if (prop.vt != VT_UI8) continue; info.Id = prop.uhVal.QuadPart; @@ -132,7 +141,7 @@ HRESULT CExternalCodecs::Load() prop.Clear(); info.Name.Empty(); - RINOK(GetHashers->GetHasherProp(i, NMethodPropID::kName, &prop)); + RINOK(GetHashers->GetHasherProp(i, NMethodPropID::kName, &prop)) if (prop.vt == VT_BSTR) info.Name.SetFromWStr_if_Ascii(prop.bstrVal); else if (prop.vt != VT_EMPTY) @@ -148,44 +157,82 @@ HRESULT CExternalCodecs::Load() #endif -bool FindMethod( +int FindMethod_Index( DECL_EXTERNAL_CODECS_LOC_VARS const AString &name, - CMethodId &methodId, UInt32 &numStreams) + bool encode, + CMethodId &methodId, + UInt32 &numStreams, + bool &isFilter) { unsigned i; for (i = 0; i < g_NumCodecs; i++) { const CCodecInfo &codec = *g_Codecs[i]; - if (StringsAreEqualNoCase_Ascii(name, codec.Name)) + if ((encode ? codec.CreateEncoder : codec.CreateDecoder) + && StringsAreEqualNoCase_Ascii(name, codec.Name)) { methodId = codec.Id; numStreams = codec.NumStreams; - return true; + isFilter = codec.IsFilter; + return (int)i; } } - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS CHECK_GLOBAL_CODECS - if (__externalCodecs) - for (i = 0; i < __externalCodecs->Codecs.Size(); i++) + if (_externalCodecs) + for (i = 0; i < _externalCodecs->Codecs.Size(); i++) { - const CCodecInfoEx &codec = __externalCodecs->Codecs[i]; - if (StringsAreEqualNoCase_Ascii(name, codec.Name)) + const CCodecInfoEx &codec = _externalCodecs->Codecs[i]; + if ((encode ? codec.EncoderIsAssigned : codec.DecoderIsAssigned) + && StringsAreEqualNoCase_Ascii(name, codec.Name)) { methodId = codec.Id; numStreams = codec.NumStreams; - return true; + isFilter = codec.IsFilter; + return (int)(g_NumCodecs + i); } } #endif - return false; + return -1; } + +static int FindMethod_Index( + DECL_EXTERNAL_CODECS_LOC_VARS + CMethodId methodId, bool encode) +{ + unsigned i; + for (i = 0; i < g_NumCodecs; i++) + { + const CCodecInfo &codec = *g_Codecs[i]; + if (codec.Id == methodId && (encode ? codec.CreateEncoder : codec.CreateDecoder)) + return (int)i; + } + + #ifdef Z7_EXTERNAL_CODECS + + CHECK_GLOBAL_CODECS + + if (_externalCodecs) + for (i = 0; i < _externalCodecs->Codecs.Size(); i++) + { + const CCodecInfoEx &codec = _externalCodecs->Codecs[i]; + if (codec.Id == methodId && (encode ? codec.EncoderIsAssigned : codec.DecoderIsAssigned)) + return (int)(g_NumCodecs + i); + } + + #endif + + return -1; +} + + bool FindMethod( DECL_EXTERNAL_CODECS_LOC_VARS CMethodId methodId, @@ -204,14 +251,14 @@ bool FindMethod( } } - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS CHECK_GLOBAL_CODECS - if (__externalCodecs) - for (i = 0; i < __externalCodecs->Codecs.Size(); i++) + if (_externalCodecs) + for (i = 0; i < _externalCodecs->Codecs.Size(); i++) { - const CCodecInfoEx &codec = __externalCodecs->Codecs[i]; + const CCodecInfoEx &codec = _externalCodecs->Codecs[i]; if (methodId == codec.Id) { name = codec.Name; @@ -240,14 +287,14 @@ bool FindHashMethod( } } - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS CHECK_GLOBAL_CODECS - if (__externalCodecs) - for (i = 0; i < __externalCodecs->Hashers.Size(); i++) + if (_externalCodecs) + for (i = 0; i < _externalCodecs->Hashers.Size(); i++) { - const CHasherInfoEx &codec = __externalCodecs->Hashers[i]; + const CHasherInfoEx &codec = _externalCodecs->Hashers[i]; if (StringsAreEqualNoCase_Ascii(name, codec.Name)) { methodId = codec.Id; @@ -269,20 +316,22 @@ void GetHashMethods( for (i = 0; i < g_NumHashers; i++) methods[i] = (*g_Hashers[i]).Id; - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS CHECK_GLOBAL_CODECS - if (__externalCodecs) - for (i = 0; i < __externalCodecs->Hashers.Size(); i++) - methods.Add(__externalCodecs->Hashers[i].Id); + if (_externalCodecs) + for (i = 0; i < _externalCodecs->Hashers.Size(); i++) + methods.Add(_externalCodecs->Hashers[i].Id); #endif } -HRESULT CreateCoder( + + +HRESULT CreateCoder_Index( DECL_EXTERNAL_CODECS_LOC_VARS - CMethodId methodId, bool encode, + unsigned i, bool encode, CMyComPtr<ICompressFilter> &filter, CCreatedCoder &cod) { @@ -290,11 +339,10 @@ HRESULT CreateCoder( cod.IsFilter = false; cod.NumStreams = 1; - unsigned i; - for (i = 0; i < g_NumCodecs; i++) + if (i < g_NumCodecs) { const CCodecInfo &codec = *g_Codecs[i]; - if (codec.Id == methodId) + // if (codec.Id == methodId) { if (encode) { @@ -319,17 +367,18 @@ HRESULT CreateCoder( } } - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS CHECK_GLOBAL_CODECS - if (__externalCodecs) + if (_externalCodecs) { + i -= g_NumCodecs; cod.IsExternal = true; - for (i = 0; i < __externalCodecs->Codecs.Size(); i++) + if (i < _externalCodecs->Codecs.Size()) { - const CCodecInfoEx &codec = __externalCodecs->Codecs[i]; - if (codec.Id == methodId) + const CCodecInfoEx &codec = _externalCodecs->Codecs[i]; + // if (codec.Id == methodId) { if (encode) { @@ -337,15 +386,15 @@ HRESULT CreateCoder( { if (codec.NumStreams == 1) { - HRESULT res = __externalCodecs->GetCodecs->CreateEncoder(i, &IID_ICompressCoder, (void **)&cod.Coder); + const HRESULT res = _externalCodecs->GetCodecs->CreateEncoder(i, &IID_ICompressCoder, (void **)&cod.Coder); if (res != S_OK && res != E_NOINTERFACE && res != CLASS_E_CLASSNOTAVAILABLE) return res; if (cod.Coder) return res; - return __externalCodecs->GetCodecs->CreateEncoder(i, &IID_ICompressFilter, (void **)&filter); + return _externalCodecs->GetCodecs->CreateEncoder(i, &IID_ICompressFilter, (void **)&filter); } cod.NumStreams = codec.NumStreams; - return __externalCodecs->GetCodecs->CreateEncoder(i, &IID_ICompressCoder2, (void **)&cod.Coder2); + return _externalCodecs->GetCodecs->CreateEncoder(i, &IID_ICompressCoder2, (void **)&cod.Coder2); } } else @@ -353,15 +402,15 @@ HRESULT CreateCoder( { if (codec.NumStreams == 1) { - HRESULT res = __externalCodecs->GetCodecs->CreateDecoder(i, &IID_ICompressCoder, (void **)&cod.Coder); + const HRESULT res = _externalCodecs->GetCodecs->CreateDecoder(i, &IID_ICompressCoder, (void **)&cod.Coder); if (res != S_OK && res != E_NOINTERFACE && res != CLASS_E_CLASSNOTAVAILABLE) return res; if (cod.Coder) return res; - return __externalCodecs->GetCodecs->CreateDecoder(i, &IID_ICompressFilter, (void **)&filter); + return _externalCodecs->GetCodecs->CreateDecoder(i, &IID_ICompressFilter, (void **)&filter); } cod.NumStreams = codec.NumStreams; - return __externalCodecs->GetCodecs->CreateDecoder(i, &IID_ICompressCoder2, (void **)&cod.Coder2); + return _externalCodecs->GetCodecs->CreateDecoder(i, &IID_ICompressCoder2, (void **)&cod.Coder2); } } } @@ -371,13 +420,50 @@ HRESULT CreateCoder( return S_OK; } -HRESULT CreateCoder( + +HRESULT CreateCoder_Index( + DECL_EXTERNAL_CODECS_LOC_VARS + unsigned index, bool encode, + CCreatedCoder &cod) +{ + CMyComPtr<ICompressFilter> filter; + const HRESULT res = CreateCoder_Index( + EXTERNAL_CODECS_LOC_VARS + index, encode, + filter, cod); + + if (filter) + { + cod.IsFilter = true; + CFilterCoder *coderSpec = new CFilterCoder(encode); + cod.Coder = coderSpec; + coderSpec->Filter = filter; + } + + return res; +} + + +HRESULT CreateCoder_Id( + DECL_EXTERNAL_CODECS_LOC_VARS + CMethodId methodId, bool encode, + CMyComPtr<ICompressFilter> &filter, + CCreatedCoder &cod) +{ + const int index = FindMethod_Index(EXTERNAL_CODECS_LOC_VARS methodId, encode); + if (index < 0) + return S_OK; + return CreateCoder_Index(EXTERNAL_CODECS_LOC_VARS (unsigned)index, encode, filter, cod); +} + + +HRESULT CreateCoder_Id( DECL_EXTERNAL_CODECS_LOC_VARS CMethodId methodId, bool encode, CCreatedCoder &cod) { CMyComPtr<ICompressFilter> filter; - HRESULT res = CreateCoder( + const HRESULT res = CreateCoder_Id( EXTERNAL_CODECS_LOC_VARS methodId, encode, filter, cod); @@ -393,13 +479,14 @@ HRESULT CreateCoder( return res; } -HRESULT CreateCoder( + +HRESULT CreateCoder_Id( DECL_EXTERNAL_CODECS_LOC_VARS CMethodId methodId, bool encode, CMyComPtr<ICompressCoder> &coder) { CCreatedCoder cod; - HRESULT res = CreateCoder( + const HRESULT res = CreateCoder_Id( EXTERNAL_CODECS_LOC_VARS methodId, encode, cod); @@ -413,7 +500,7 @@ HRESULT CreateFilter( CMyComPtr<ICompressFilter> &filter) { CCreatedCoder cod; - return CreateCoder( + return CreateCoder_Id( EXTERNAL_CODECS_LOC_VARS methodId, encode, filter, cod); @@ -440,18 +527,18 @@ HRESULT CreateHasher( } } - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS CHECK_GLOBAL_CODECS - if (!hasher && __externalCodecs) - for (i = 0; i < __externalCodecs->Hashers.Size(); i++) + if (!hasher && _externalCodecs) + for (i = 0; i < _externalCodecs->Hashers.Size(); i++) { - const CHasherInfoEx &codec = __externalCodecs->Hashers[i]; + const CHasherInfoEx &codec = _externalCodecs->Hashers[i]; if (codec.Id == methodId) { name = codec.Name; - return __externalCodecs->GetHashers->CreateHasher((UInt32)i, &hasher); + return _externalCodecs->GetHashers->CreateHasher((UInt32)i, &hasher); } } diff --git a/3rdparty/lzma/CPP/7zip/Common/CreateCoder.h b/3rdparty/lzma/CPP/7zip/Common/CreateCoder.h index f06064b6a6f..709fe83c1d7 100644 --- a/3rdparty/lzma/CPP/7zip/Common/CreateCoder.h +++ b/3rdparty/lzma/CPP/7zip/Common/CreateCoder.h @@ -1,7 +1,7 @@ // CreateCoder.h -#ifndef __CREATE_CODER_H -#define __CREATE_CODER_H +#ifndef ZIP7_INC_CREATE_CODER_H +#define ZIP7_INC_CREATE_CODER_H #include "../../Common/MyCom.h" #include "../../Common/MyString.h" @@ -11,10 +11,10 @@ #include "MethodId.h" /* - if EXTERNAL_CODECS is not defined, the code supports only codecs that + if Z7_EXTERNAL_CODECS is not defined, the code supports only codecs that are statically linked at compile-time and link-time. - if EXTERNAL_CODECS is defined, the code supports also codecs from another + if Z7_EXTERNAL_CODECS is defined, the code supports also codecs from another executable modules, that can be linked dynamically at run-time: - EXE module can use codecs from external DLL files. - DLL module can use codecs from external EXE and DLL files. @@ -26,7 +26,7 @@ 2) External codecs */ -#ifdef EXTERNAL_CODECS +#ifdef Z7_EXTERNAL_CODECS struct CCodecInfoEx { @@ -35,8 +35,9 @@ struct CCodecInfoEx UInt32 NumStreams; bool EncoderIsAssigned; bool DecoderIsAssigned; + bool IsFilter; // it's unused - CCodecInfoEx(): EncoderIsAssigned(false), DecoderIsAssigned(false) {} + CCodecInfoEx(): EncoderIsAssigned(false), DecoderIsAssigned(false), IsFilter(false) {} }; struct CHasherInfoEx @@ -45,13 +46,17 @@ struct CHasherInfoEx AString Name; }; -#define PUBLIC_ISetCompressCodecsInfo public ISetCompressCodecsInfo, -#define QUERY_ENTRY_ISetCompressCodecsInfo MY_QUERYINTERFACE_ENTRY(ISetCompressCodecsInfo) -#define DECL_ISetCompressCodecsInfo STDMETHOD(SetCompressCodecsInfo)(ICompressCodecsInfo *compressCodecsInfo); -#define IMPL_ISetCompressCodecsInfo2(x) \ -STDMETHODIMP x::SetCompressCodecsInfo(ICompressCodecsInfo *compressCodecsInfo) { \ - COM_TRY_BEGIN __externalCodecs.GetCodecs = compressCodecsInfo; return __externalCodecs.Load(); COM_TRY_END } -#define IMPL_ISetCompressCodecsInfo IMPL_ISetCompressCodecsInfo2(CHandler) +#define Z7_PUBLIC_ISetCompressCodecsInfo_IFEC \ + public ISetCompressCodecsInfo, +#define Z7_COM_QI_ENTRY_ISetCompressCodecsInfo_IFEC \ + Z7_COM_QI_ENTRY(ISetCompressCodecsInfo) +#define DECL_ISetCompressCodecsInfo \ + Z7_COM7F_IMP(SetCompressCodecsInfo(ICompressCodecsInfo *compressCodecsInfo)) +#define IMPL_ISetCompressCodecsInfo2(cls) \ + Z7_COM7F_IMF(cls::SetCompressCodecsInfo(ICompressCodecsInfo *compressCodecsInfo)) \ + { COM_TRY_BEGIN _externalCodecs.GetCodecs = compressCodecsInfo; \ + return _externalCodecs.Load(); COM_TRY_END } +#define IMPL_ISetCompressCodecsInfo IMPL_ISetCompressCodecsInfo2(CHandler) struct CExternalCodecs { @@ -82,26 +87,27 @@ struct CExternalCodecs extern CExternalCodecs g_ExternalCodecs; -#define EXTERNAL_CODECS_VARS2 (__externalCodecs.IsSet() ? &__externalCodecs : &g_ExternalCodecs) -#define EXTERNAL_CODECS_VARS2_L (&__externalCodecs) +#define EXTERNAL_CODECS_VARS2 (_externalCodecs.IsSet() ? &_externalCodecs : &g_ExternalCodecs) +#define EXTERNAL_CODECS_VARS2_L (&_externalCodecs) #define EXTERNAL_CODECS_VARS2_G (&g_ExternalCodecs) -#define DECL_EXTERNAL_CODECS_VARS CExternalCodecs __externalCodecs; +#define DECL_EXTERNAL_CODECS_VARS CExternalCodecs _externalCodecs; #define EXTERNAL_CODECS_VARS EXTERNAL_CODECS_VARS2, #define EXTERNAL_CODECS_VARS_L EXTERNAL_CODECS_VARS2_L, #define EXTERNAL_CODECS_VARS_G EXTERNAL_CODECS_VARS2_G, -#define DECL_EXTERNAL_CODECS_LOC_VARS2 const CExternalCodecs *__externalCodecs -#define EXTERNAL_CODECS_LOC_VARS2 __externalCodecs +#define DECL_EXTERNAL_CODECS_LOC_VARS2 const CExternalCodecs *_externalCodecs +#define DECL_EXTERNAL_CODECS_LOC_VARS DECL_EXTERNAL_CODECS_LOC_VARS2, +#define DECL_EXTERNAL_CODECS_LOC_VARS_DECL DECL_EXTERNAL_CODECS_LOC_VARS2; -#define DECL_EXTERNAL_CODECS_LOC_VARS DECL_EXTERNAL_CODECS_LOC_VARS2, -#define EXTERNAL_CODECS_LOC_VARS EXTERNAL_CODECS_LOC_VARS2, +#define EXTERNAL_CODECS_LOC_VARS2 _externalCodecs +#define EXTERNAL_CODECS_LOC_VARS EXTERNAL_CODECS_LOC_VARS2, #else -#define PUBLIC_ISetCompressCodecsInfo -#define QUERY_ENTRY_ISetCompressCodecsInfo +#define Z7_PUBLIC_ISetCompressCodecsInfo_IFEC +#define Z7_COM_QI_ENTRY_ISetCompressCodecsInfo_IFEC #define DECL_ISetCompressCodecsInfo #define IMPL_ISetCompressCodecsInfo #define EXTERNAL_CODECS_VARS2 @@ -110,19 +116,20 @@ extern CExternalCodecs g_ExternalCodecs; #define EXTERNAL_CODECS_VARS_L #define EXTERNAL_CODECS_VARS_G #define DECL_EXTERNAL_CODECS_LOC_VARS2 -#define EXTERNAL_CODECS_LOC_VARS2 #define DECL_EXTERNAL_CODECS_LOC_VARS +#define DECL_EXTERNAL_CODECS_LOC_VARS_DECL +#define EXTERNAL_CODECS_LOC_VARS2 #define EXTERNAL_CODECS_LOC_VARS #endif - - - -bool FindMethod( +int FindMethod_Index( DECL_EXTERNAL_CODECS_LOC_VARS const AString &name, - CMethodId &methodId, UInt32 &numStreams); + bool encode, + CMethodId &methodId, + UInt32 &numStreams, + bool &isFilter); bool FindMethod( DECL_EXTERNAL_CODECS_LOC_VARS @@ -152,18 +159,29 @@ struct CCreatedCoder }; -HRESULT CreateCoder( +HRESULT CreateCoder_Index( + DECL_EXTERNAL_CODECS_LOC_VARS + unsigned codecIndex, bool encode, + CMyComPtr<ICompressFilter> &filter, + CCreatedCoder &cod); + +HRESULT CreateCoder_Index( + DECL_EXTERNAL_CODECS_LOC_VARS + unsigned index, bool encode, + CCreatedCoder &cod); + +HRESULT CreateCoder_Id( DECL_EXTERNAL_CODECS_LOC_VARS CMethodId methodId, bool encode, CMyComPtr<ICompressFilter> &filter, CCreatedCoder &cod); -HRESULT CreateCoder( +HRESULT CreateCoder_Id( DECL_EXTERNAL_CODECS_LOC_VARS CMethodId methodId, bool encode, CCreatedCoder &cod); -HRESULT CreateCoder( +HRESULT CreateCoder_Id( DECL_EXTERNAL_CODECS_LOC_VARS CMethodId methodId, bool encode, CMyComPtr<ICompressCoder> &coder); diff --git a/3rdparty/lzma/CPP/7zip/Common/FilePathAutoRename.cpp b/3rdparty/lzma/CPP/7zip/Common/FilePathAutoRename.cpp index d186e599333..1ebfd72bb93 100644 --- a/3rdparty/lzma/CPP/7zip/Common/FilePathAutoRename.cpp +++ b/3rdparty/lzma/CPP/7zip/Common/FilePathAutoRename.cpp @@ -2,9 +2,6 @@ #include "StdAfx.h" -#include "../../Common/Defs.h" -#include "../../Common/IntToString.h" - #include "../../Windows/FileFind.h" #include "FilePathAutoRename.h" @@ -14,10 +11,8 @@ using namespace NWindows; static bool MakeAutoName(const FString &name, const FString &extension, UInt32 value, FString &path) { - char temp[16]; - ConvertUInt32ToString(value, temp); path = name; - path.AddAscii(temp); + path.Add_UInt32(value); path += extension; return NFile::NFind::DoesFileOrDirExist(path); } @@ -31,10 +26,10 @@ bool AutoRenamePath(FString &path) FString extension; if (dotPos > slashPos + 1) { - name.DeleteFrom(dotPos); - extension = path.Ptr(dotPos); + name.DeleteFrom((unsigned)dotPos); + extension = path.Ptr((unsigned)dotPos); } - name += FTEXT('_'); + name += '_'; FString temp; diff --git a/3rdparty/lzma/CPP/7zip/Common/FilePathAutoRename.h b/3rdparty/lzma/CPP/7zip/Common/FilePathAutoRename.h index 7b576591c9a..ac36882312d 100644 --- a/3rdparty/lzma/CPP/7zip/Common/FilePathAutoRename.h +++ b/3rdparty/lzma/CPP/7zip/Common/FilePathAutoRename.h @@ -1,7 +1,7 @@ // FilePathAutoRename.h -#ifndef __FILE_PATH_AUTO_RENAME_H -#define __FILE_PATH_AUTO_RENAME_H +#ifndef ZIP7_INC_FILE_PATH_AUTO_RENAME_H +#define ZIP7_INC_FILE_PATH_AUTO_RENAME_H #include "../../Common/MyString.h" diff --git a/3rdparty/lzma/CPP/7zip/Common/FileStreams.cpp b/3rdparty/lzma/CPP/7zip/Common/FileStreams.cpp index f3a322fc9be..429863630ed 100644 --- a/3rdparty/lzma/CPP/7zip/Common/FileStreams.cpp +++ b/3rdparty/lzma/CPP/7zip/Common/FileStreams.cpp @@ -2,42 +2,71 @@ #include "StdAfx.h" +// #include <stdio.h> + #ifndef _WIN32 #include <fcntl.h> #include <unistd.h> #include <errno.h> +#include <grp.h> +#include <pwd.h> + +// for major()/minor(): +#include <sys/types.h> +#if defined(__FreeBSD__) || defined(BSD) || defined(__APPLE__) +#else +#ifndef major +#include <sys/sysmacros.h> #endif +#endif + +#endif // _WIN32 + +#include "../../Windows/FileFind.h" -#ifdef SUPPORT_DEVICE_FILE +#ifdef Z7_DEVICE_FILE #include "../../../C/Alloc.h" #include "../../Common/Defs.h" #endif +#include "../PropID.h" + #include "FileStreams.h" -static inline HRESULT ConvertBoolToHRESULT(bool result) +static inline HRESULT GetLastError_HRESULT() { - #ifdef _WIN32 - if (result) - return S_OK; DWORD lastError = ::GetLastError(); if (lastError == 0) return E_FAIL; return HRESULT_FROM_WIN32(lastError); - #else - return result ? S_OK: E_FAIL; - #endif } +static inline HRESULT ConvertBoolToHRESULT(bool result) +{ + if (result) + return S_OK; + return GetLastError_HRESULT(); +} + +#ifdef Z7_DEVICE_FILE static const UInt32 kClusterSize = 1 << 18; +#endif + CInFileStream::CInFileStream(): - #ifdef SUPPORT_DEVICE_FILE + #ifdef Z7_DEVICE_FILE VirtPos(0), PhyPos(0), - Buf(0), + Buf(NULL), BufSize(0), - #endif + #endif + #ifndef _WIN32 + _uid(0), + _gid(0), + StoreOwnerId(false), + StoreOwnerName(false), + #endif + _info_WasLoaded(false), SupportHardLinks(false), Callback(NULL), CallbackRef(0) @@ -46,19 +75,19 @@ CInFileStream::CInFileStream(): CInFileStream::~CInFileStream() { - #ifdef SUPPORT_DEVICE_FILE + #ifdef Z7_DEVICE_FILE MidFree(Buf); #endif if (Callback) - Callback->InFileStream_On_Destroy(CallbackRef); + Callback->InFileStream_On_Destroy(this, CallbackRef); } -STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { - #ifdef USE_WIN_FILE + #ifdef Z7_FILE_STREAMS_USE_WIN_FILE - #ifdef SUPPORT_DEVICE_FILE + #ifdef Z7_DEVICE_FILE if (processedSize) *processedSize = 0; if (size == 0) @@ -69,7 +98,7 @@ STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) { if (VirtPos >= File.Size) return VirtPos == File.Size ? S_OK : E_FAIL; - UInt64 rem = File.Size - VirtPos; + const UInt64 rem = File.Size - VirtPos; if (size > rem) size = (UInt32)rem; } @@ -77,13 +106,13 @@ STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) { const UInt32 mask = kClusterSize - 1; const UInt64 mask2 = ~(UInt64)mask; - UInt64 alignedPos = VirtPos & mask2; + const UInt64 alignedPos = VirtPos & mask2; if (BufSize > 0 && BufStartPos == alignedPos) { - UInt32 pos = (UInt32)VirtPos & mask; + const UInt32 pos = (UInt32)VirtPos & mask; if (pos >= BufSize) return S_OK; - UInt32 rem = MyMin(BufSize - pos, size); + const UInt32 rem = MyMin(BufSize - pos, size); memcpy(data, Buf + pos, rem); VirtPos += rem; if (processedSize) @@ -92,7 +121,7 @@ STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) } bool useBuf = false; - if ((VirtPos & mask) != 0 || ((ptrdiff_t)data & mask) != 0 ) + if ((VirtPos & mask) != 0 || ((size_t)(ptrdiff_t)data & mask) != 0 ) useBuf = true; else { @@ -111,7 +140,7 @@ STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) if (alignedPos != PhyPos) { UInt64 realNewPosition; - bool result = File.Seek(alignedPos, FILE_BEGIN, realNewPosition); + const bool result = File.Seek((Int64)alignedPos, FILE_BEGIN, realNewPosition); if (!result) return ConvertBoolToHRESULT(result); PhyPos = realNewPosition; @@ -128,7 +157,7 @@ STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) if (!Buf) return E_OUTOFMEMORY; } - bool result = File.Read1(Buf, readSize, BufSize); + const bool result = File.Read1(Buf, readSize, BufSize); if (!result) return ConvertBoolToHRESULT(result); @@ -140,7 +169,7 @@ STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) if (VirtPos != PhyPos) { UInt64 realNewPosition; - bool result = File.Seek(VirtPos, FILE_BEGIN, realNewPosition); + bool result = File.Seek((Int64)VirtPos, FILE_BEGIN, realNewPosition); if (!result) return ConvertBoolToHRESULT(result); PhyPos = VirtPos = realNewPosition; @@ -149,11 +178,11 @@ STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) #endif UInt32 realProcessedSize; - bool result = File.ReadPart(data, size, realProcessedSize); + const bool result = File.ReadPart(data, size, realProcessedSize); if (processedSize) *processedSize = realProcessedSize; - #ifdef SUPPORT_DEVICE_FILE + #ifdef Z7_DEVICE_FILE VirtPos += realProcessedSize; PhyPos += realProcessedSize; #endif @@ -161,37 +190,31 @@ STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) if (result) return S_OK; + #else // Z7_FILE_STREAMS_USE_WIN_FILE + + if (processedSize) + *processedSize = 0; + const ssize_t res = File.read_part(data, (size_t)size); + if (res != -1) { - DWORD error = ::GetLastError(); + if (processedSize) + *processedSize = (UInt32)res; + return S_OK; + } + #endif // Z7_FILE_STREAMS_USE_WIN_FILE + { + const DWORD error = ::GetLastError(); if (Callback) return Callback->InFileStream_On_Error(CallbackRef, error); if (error == 0) return E_FAIL; - return HRESULT_FROM_WIN32(error); } - - #else - - if (processedSize) - *processedSize = 0; - ssize_t res = File.Read(data, (size_t)size); - if (res == -1) - { - if (Callback) - return Callback->InFileStream_On_Error(CallbackRef, E_FAIL); - return E_FAIL; - } - if (processedSize) - *processedSize = (UInt32)res; - return S_OK; - - #endif } #ifdef UNDER_CE -STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { size_t s2 = fread(data, 1, size, stdin); int error = ferror(stdin); @@ -202,7 +225,7 @@ STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSi return E_FAIL; } #else -STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { #ifdef _WIN32 @@ -228,7 +251,7 @@ STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSi } while (res < 0 && (errno == EINTR)); if (res == -1) - return E_FAIL; + return GetLastError_HRESULT(); if (processedSize) *processedSize = (UInt32)res; return S_OK; @@ -238,14 +261,14 @@ STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSi #endif -STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(CInFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { if (seekOrigin >= 3) return STG_E_INVALIDFUNCTION; - #ifdef USE_WIN_FILE + #ifdef Z7_FILE_STREAMS_USE_WIN_FILE - #ifdef SUPPORT_DEVICE_FILE + #ifdef Z7_DEVICE_FILE if (File.IsDeviceFile && (File.SizeDefined || seekOrigin != STREAM_SEEK_END)) { switch (seekOrigin) @@ -257,29 +280,40 @@ STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPos } if (offset < 0) return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - VirtPos = offset; + VirtPos = (UInt64)offset; if (newPosition) - *newPosition = offset; + *newPosition = (UInt64)offset; return S_OK; } #endif - UInt64 realNewPosition; - bool result = File.Seek(offset, seekOrigin, realNewPosition); + UInt64 realNewPosition = 0; + const bool result = File.Seek(offset, seekOrigin, realNewPosition); + const HRESULT hres = ConvertBoolToHRESULT(result); + + /* 21.07: new File.Seek() in 21.07 already returns correct (realNewPosition) + in case of error. So we don't need additional code below */ + // if (!result) { realNewPosition = 0; File.GetPosition(realNewPosition); } - #ifdef SUPPORT_DEVICE_FILE + #ifdef Z7_DEVICE_FILE PhyPos = VirtPos = realNewPosition; #endif if (newPosition) *newPosition = realNewPosition; - return ConvertBoolToHRESULT(result); + + return hres; #else - off_t res = File.Seek((off_t)offset, seekOrigin); + const off_t res = File.seek((off_t)offset, (int)seekOrigin); if (res == -1) - return E_FAIL; + { + const HRESULT hres = GetLastError_HRESULT(); + if (newPosition) + *newPosition = (UInt64)File.seekToCur(); + return hres; + } if (newPosition) *newPosition = (UInt64)res; return S_OK; @@ -287,17 +321,25 @@ STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPos #endif } -STDMETHODIMP CInFileStream::GetSize(UInt64 *size) +Z7_COM7F_IMF(CInFileStream::GetSize(UInt64 *size)) { return ConvertBoolToHRESULT(File.GetLength(*size)); } -#ifdef USE_WIN_FILE +#ifdef Z7_FILE_STREAMS_USE_WIN_FILE -STDMETHODIMP CInFileStream::GetProps(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib) +Z7_COM7F_IMF(CInFileStream::GetProps(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib)) { + if (!_info_WasLoaded) + { + RINOK(ReloadProps()) + } + const BY_HANDLE_FILE_INFORMATION &info = _info; + /* BY_HANDLE_FILE_INFORMATION info; - if (File.GetFileInformation(&info)) + if (!File.GetFileInformation(&info)) + return GetLastError_HRESULT(); + */ { if (size) *size = (((UInt64)info.nFileSizeHigh) << 32) + info.nFileSizeLow; if (cTime) *cTime = info.ftCreationTime; @@ -306,13 +348,20 @@ STDMETHODIMP CInFileStream::GetProps(UInt64 *size, FILETIME *cTime, FILETIME *aT if (attrib) *attrib = info.dwFileAttributes; return S_OK; } - return GetLastError(); } -STDMETHODIMP CInFileStream::GetProps2(CStreamFileProps *props) +Z7_COM7F_IMF(CInFileStream::GetProps2(CStreamFileProps *props)) { + if (!_info_WasLoaded) + { + RINOK(ReloadProps()) + } + const BY_HANDLE_FILE_INFORMATION &info = _info; + /* BY_HANDLE_FILE_INFORMATION info; - if (File.GetFileInformation(&info)) + if (!File.GetFileInformation(&info)) + return GetLastError_HRESULT(); + */ { props->Size = (((UInt64)info.nFileSizeHigh) << 32) + info.nFileSizeLow; props->VolID = info.dwVolumeSerialNumber; @@ -325,11 +374,300 @@ STDMETHODIMP CInFileStream::GetProps2(CStreamFileProps *props) props->MTime = info.ftLastWriteTime; return S_OK; } - return GetLastError(); +} + +Z7_COM7F_IMF(CInFileStream::GetProperty(PROPID propID, PROPVARIANT *value)) +{ + if (!_info_WasLoaded) + { + RINOK(ReloadProps()) + } + + if (!_info_WasLoaded) + return S_OK; + + NWindows::NCOM::CPropVariant prop; + + #ifdef Z7_DEVICE_FILE + if (File.IsDeviceFile) + { + switch (propID) + { + case kpidSize: + if (File.SizeDefined) + prop = File.Size; + break; + // case kpidAttrib: prop = (UInt32)0; break; + case kpidPosixAttrib: + { + prop = (UInt32)NWindows::NFile::NFind::NAttributes:: + Get_PosixMode_From_WinAttrib(0); + /* GNU TAR by default can't extract file with MY_LIN_S_IFBLK attribute + so we don't use MY_LIN_S_IFBLK here */ + // prop = (UInt32)(MY_LIN_S_IFBLK | 0600); // for debug + break; + } + /* + case kpidDeviceMajor: + prop = (UInt32)8; // id for SCSI type device (sda) + break; + case kpidDeviceMinor: + prop = (UInt32)0; + break; + */ + } + } + else + #endif + { + switch (propID) + { + case kpidSize: + { + const UInt64 size = (((UInt64)_info.nFileSizeHigh) << 32) + _info.nFileSizeLow; + prop = size; + break; + } + case kpidAttrib: prop = (UInt32)_info.dwFileAttributes; break; + case kpidCTime: PropVariant_SetFrom_FiTime(prop, _info.ftCreationTime); break; + case kpidATime: PropVariant_SetFrom_FiTime(prop, _info.ftLastAccessTime); break; + case kpidMTime: PropVariant_SetFrom_FiTime(prop, _info.ftLastWriteTime); break; + case kpidPosixAttrib: + prop = (UInt32)NWindows::NFile::NFind::NAttributes:: + Get_PosixMode_From_WinAttrib(_info.dwFileAttributes); + // | (UInt32)(1 << 21); // for debug + break; + } + } + prop.Detach(value); + return S_OK; +} + + +Z7_COM7F_IMF(CInFileStream::ReloadProps()) +{ + #ifdef Z7_DEVICE_FILE + if (File.IsDeviceFile) + { + memset(&_info, 0, sizeof(_info)); + if (File.SizeDefined) + { + _info.nFileSizeHigh = (DWORD)(File.Size >> 32); + _info.nFileSizeLow = (DWORD)(File.Size); + } + _info.nNumberOfLinks = 1; + _info_WasLoaded = true; + return S_OK; + } + #endif + _info_WasLoaded = File.GetFileInformation(&_info); + if (!_info_WasLoaded) + return GetLastError_HRESULT(); + return S_OK; +} + + +#elif !defined(_WIN32) + +Z7_COM7F_IMF(CInFileStream::GetProps(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib)) +{ + if (!_info_WasLoaded) + { + RINOK(ReloadProps()) + } + const struct stat &st = _info; + /* + struct stat st; + if (File.my_fstat(&st) != 0) + return GetLastError_HRESULT(); + */ + + if (size) *size = (UInt64)st.st_size; + if (cTime) FiTime_To_FILETIME (ST_CTIME(st), *cTime); + if (aTime) FiTime_To_FILETIME (ST_ATIME(st), *aTime); + if (mTime) FiTime_To_FILETIME (ST_MTIME(st), *mTime); + if (attrib) *attrib = NWindows::NFile::NFind::Get_WinAttribPosix_From_PosixMode(st.st_mode); + + return S_OK; +} + +// #include <stdio.h> + +Z7_COM7F_IMF(CInFileStream::GetProps2(CStreamFileProps *props)) +{ + if (!_info_WasLoaded) + { + RINOK(ReloadProps()) + } + const struct stat &st = _info; + /* + struct stat st; + if (File.my_fstat(&st) != 0) + return GetLastError_HRESULT(); + */ + + props->Size = (UInt64)st.st_size; + /* + dev_t stat::st_dev: + GCC:Linux long unsigned int : __dev_t + Mac: int + */ + props->VolID = (UInt64)(Int64)st.st_dev; + props->FileID_Low = st.st_ino; + props->FileID_High = 0; + props->NumLinks = (UInt32)st.st_nlink; // we reduce to UInt32 from (nlink_t) that is (unsigned long) + props->Attrib = NWindows::NFile::NFind::Get_WinAttribPosix_From_PosixMode(st.st_mode); + + FiTime_To_FILETIME (ST_CTIME(st), props->CTime); + FiTime_To_FILETIME (ST_ATIME(st), props->ATime); + FiTime_To_FILETIME (ST_MTIME(st), props->MTime); + + /* + printf("\nGetProps2() NumLinks=%d = st_dev=%d st_ino = %d\n" + , (unsigned)(props->NumLinks) + , (unsigned)(st.st_dev) + , (unsigned)(st.st_ino) + ); + */ + + return S_OK; +} + +Z7_COM7F_IMF(CInFileStream::GetProperty(PROPID propID, PROPVARIANT *value)) +{ + if (!_info_WasLoaded) + { + RINOK(ReloadProps()) + } + + if (!_info_WasLoaded) + return S_OK; + + const struct stat &st = _info; + + NWindows::NCOM::CPropVariant prop; + { + switch (propID) + { + case kpidSize: prop = (UInt64)st.st_size; break; + case kpidAttrib: + prop = (UInt32)NWindows::NFile::NFind::Get_WinAttribPosix_From_PosixMode(st.st_mode); + break; + case kpidCTime: PropVariant_SetFrom_FiTime(prop, ST_CTIME(st)); break; + case kpidATime: PropVariant_SetFrom_FiTime(prop, ST_ATIME(st)); break; + case kpidMTime: PropVariant_SetFrom_FiTime(prop, ST_MTIME(st)); break; + case kpidPosixAttrib: prop = (UInt32)st.st_mode; break; + + #if defined(__APPLE__) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wsign-conversion" + #endif + + case kpidDeviceMajor: + { + // printf("\nst.st_rdev = %d\n", st.st_rdev); + if (S_ISCHR(st.st_mode) || + S_ISBLK(st.st_mode)) + prop = (UInt32)(major(st.st_rdev)); // + 1000); + // prop = (UInt32)12345678; // for debug + break; + } + + case kpidDeviceMinor: + if (S_ISCHR(st.st_mode) || + S_ISBLK(st.st_mode)) + prop = (UInt32)(minor(st.st_rdev)); // + 100); + // prop = (UInt32)(st.st_rdev); // for debug + // printf("\nst.st_rdev = %d\n", st.st_rdev); + // prop = (UInt32)123456789; // for debug + break; + + #if defined(__APPLE__) + #pragma GCC diagnostic pop + #endif + + /* + case kpidDevice: + if (S_ISCHR(st.st_mode) || + S_ISBLK(st.st_mode)) + prop = (UInt64)(st.st_rdev); + break; + */ + + case kpidUserId: + { + if (StoreOwnerId) + prop = (UInt32)st.st_uid; + break; + } + case kpidGroupId: + { + if (StoreOwnerId) + prop = (UInt32)st.st_gid; + break; + } + case kpidUser: + { + if (StoreOwnerName) + { + const uid_t uid = st.st_uid; + { + if (!OwnerName.IsEmpty() && _uid == uid) + prop = OwnerName; + else + { + const passwd *pw = getpwuid(uid); + if (pw) + { + // we can use utf-8 here. + // prop = pw->pw_name; + } + } + } + } + break; + } + case kpidGroup: + { + if (StoreOwnerName) + { + const uid_t gid = st.st_gid; + { + if (!OwnerGroup.IsEmpty() && _gid == gid) + prop = OwnerGroup; + else + { + const group *gr = getgrgid(gid); + if (gr) + { + // we can use utf-8 here. + // prop = gr->gr_name; + } + } + } + } + break; + } + } + } + prop.Detach(value); + return S_OK; +} + + +Z7_COM7F_IMF(CInFileStream::ReloadProps()) +{ + _info_WasLoaded = (File.my_fstat(&_info) == 0); + if (!_info_WasLoaded) + return GetLastError_HRESULT(); + return S_OK; } #endif + + + ////////////////////////// // COutFileStream @@ -338,12 +676,12 @@ HRESULT COutFileStream::Close() return ConvertBoolToHRESULT(File.Close()); } -STDMETHODIMP COutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(COutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { - #ifdef USE_WIN_FILE + #ifdef Z7_FILE_STREAMS_USE_WIN_FILE UInt32 realProcessedSize; - bool result = File.Write(data, size, realProcessedSize); + const bool result = File.Write(data, size, realProcessedSize); ProcessedSize += realProcessedSize; if (processedSize) *processedSize = realProcessedSize; @@ -353,35 +691,36 @@ STDMETHODIMP COutFileStream::Write(const void *data, UInt32 size, UInt32 *proces if (processedSize) *processedSize = 0; - ssize_t res = File.Write(data, (size_t)size); - if (res == -1) - return E_FAIL; + size_t realProcessedSize; + const ssize_t res = File.write_full(data, (size_t)size, realProcessedSize); + ProcessedSize += realProcessedSize; if (processedSize) - *processedSize = (UInt32)res; - ProcessedSize += res; + *processedSize = (UInt32)realProcessedSize; + if (res == -1) + return GetLastError_HRESULT(); return S_OK; #endif } -STDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { if (seekOrigin >= 3) return STG_E_INVALIDFUNCTION; - #ifdef USE_WIN_FILE + #ifdef Z7_FILE_STREAMS_USE_WIN_FILE - UInt64 realNewPosition; - bool result = File.Seek(offset, seekOrigin, realNewPosition); + UInt64 realNewPosition = 0; + const bool result = File.Seek(offset, seekOrigin, realNewPosition); if (newPosition) *newPosition = realNewPosition; return ConvertBoolToHRESULT(result); #else - off_t res = File.Seek((off_t)offset, seekOrigin); + const off_t res = File.seek((off_t)offset, (int)seekOrigin); if (res == -1) - return E_FAIL; + return GetLastError_HRESULT(); if (newPosition) *newPosition = (UInt64)res; return S_OK; @@ -389,23 +728,9 @@ STDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPo #endif } -STDMETHODIMP COutFileStream::SetSize(UInt64 newSize) +Z7_COM7F_IMF(COutFileStream::SetSize(UInt64 newSize)) { - #ifdef USE_WIN_FILE - - UInt64 currentPos; - if (!File.Seek(0, FILE_CURRENT, currentPos)) - return E_FAIL; - bool result = File.SetLength(newSize); - UInt64 currentPos2; - result = result && File.Seek(currentPos, currentPos2); - return result ? S_OK : E_FAIL; - - #else - - return E_FAIL; - - #endif + return ConvertBoolToHRESULT(File.SetLength_KeepPosition(newSize)); } HRESULT COutFileStream::GetSize(UInt64 *size) @@ -415,7 +740,7 @@ HRESULT COutFileStream::GetSize(UInt64 *size) #ifdef UNDER_CE -STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { size_t s2 = fwrite(data, 1, size, stdout); if (processedSize) @@ -425,7 +750,7 @@ STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *pro #else -STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -462,7 +787,7 @@ STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *pro while (res < 0 && (errno == EINTR)); if (res == -1) - return E_FAIL; + return GetLastError_HRESULT(); _size += (size_t)res; if (processedSize) diff --git a/3rdparty/lzma/CPP/7zip/Common/FileStreams.h b/3rdparty/lzma/CPP/7zip/Common/FileStreams.h index ef2986fdd88..7e1b086b139 100644 --- a/3rdparty/lzma/CPP/7zip/Common/FileStreams.h +++ b/3rdparty/lzma/CPP/7zip/Common/FileStreams.h @@ -1,50 +1,75 @@ // FileStreams.h -#ifndef __FILE_STREAMS_H -#define __FILE_STREAMS_H +#ifndef ZIP7_INC_FILE_STREAMS_H +#define ZIP7_INC_FILE_STREAMS_H #ifdef _WIN32 -#define USE_WIN_FILE +#define Z7_FILE_STREAMS_USE_WIN_FILE #endif +#include "../../Common/MyCom.h" #include "../../Common/MyString.h" -#ifdef USE_WIN_FILE #include "../../Windows/FileIO.h" -#else -#include "../../Common/C_FileIO.h" -#endif - -#include "../../Common/MyCom.h" #include "../IStream.h" -#ifdef _WIN32 -typedef UINT_PTR My_UINT_PTR; -#else -typedef UINT My_UINT_PTR; -#endif +#include "UniqBlocks.h" -struct IInFileStream_Callback + +class CInFileStream; + +Z7_PURE_INTERFACES_BEGIN +DECLARE_INTERFACE(IInFileStream_Callback) { - virtual HRESULT InFileStream_On_Error(My_UINT_PTR val, DWORD error) = 0; - virtual void InFileStream_On_Destroy(My_UINT_PTR val) = 0; + virtual HRESULT InFileStream_On_Error(UINT_PTR val, DWORD error) = 0; + virtual void InFileStream_On_Destroy(CInFileStream *stream, UINT_PTR val) = 0; }; - -class CInFileStream: +Z7_PURE_INTERFACES_END + + +/* +Z7_CLASS_IMP_COM_5( + CInFileStream + , IInStream + , IStreamGetSize + , IStreamGetProps + , IStreamGetProps2 + , IStreamGetProp +) +*/ +Z7_class_final(CInFileStream) : public IInStream, public IStreamGetSize, - #ifdef USE_WIN_FILE public IStreamGetProps, public IStreamGetProps2, - #endif + public IStreamGetProp, public CMyUnknownImp { + Z7_COM_UNKNOWN_IMP_5( + IInStream, + IStreamGetSize, + IStreamGetProps, + IStreamGetProps2, + IStreamGetProp) + + Z7_IFACE_COM7_IMP(ISequentialInStream) + Z7_IFACE_COM7_IMP(IInStream) +public: + Z7_IFACE_COM7_IMP(IStreamGetSize) +private: + Z7_IFACE_COM7_IMP(IStreamGetProps) public: - #ifdef USE_WIN_FILE + Z7_IFACE_COM7_IMP(IStreamGetProps2) + Z7_IFACE_COM7_IMP(IStreamGetProp) + +private: NWindows::NFile::NIO::CInFile File; +public: + + #ifdef Z7_FILE_STREAMS_USE_WIN_FILE - #ifdef SUPPORT_DEVICE_FILE + #ifdef Z7_DEVICE_FILE UInt64 VirtPos; UInt64 PhyPos; UInt64 BufStartPos; @@ -52,70 +77,68 @@ public: UInt32 BufSize; #endif - #else - NC::NFile::NIO::CInFile File; #endif + #ifdef _WIN32 + BY_HANDLE_FILE_INFORMATION _info; + #else + struct stat _info; + UInt32 _uid; + UInt32 _gid; + UString OwnerName; + UString OwnerGroup; + bool StoreOwnerId; + bool StoreOwnerName; + #endif + + bool _info_WasLoaded; bool SupportHardLinks; - IInFileStream_Callback *Callback; - My_UINT_PTR CallbackRef; - - virtual ~CInFileStream(); + UINT_PTR CallbackRef; CInFileStream(); + ~CInFileStream(); + + void Set_PreserveATime(bool v) + { + File.PreserveATime = v; + } + + bool GetLength(UInt64 &length) const throw() + { + return File.GetLength(length); + } bool Open(CFSTR fileName) { + _info_WasLoaded = false; return File.Open(fileName); } bool OpenShared(CFSTR fileName, bool shareForWrite) { + _info_WasLoaded = false; return File.OpenShared(fileName, shareForWrite); } - - MY_QUERYINTERFACE_BEGIN2(IInStream) - MY_QUERYINTERFACE_ENTRY(IStreamGetSize) - #ifdef USE_WIN_FILE - MY_QUERYINTERFACE_ENTRY(IStreamGetProps) - MY_QUERYINTERFACE_ENTRY(IStreamGetProps2) - #endif - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - - STDMETHOD(GetSize)(UInt64 *size); - #ifdef USE_WIN_FILE - STDMETHOD(GetProps)(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib); - STDMETHOD(GetProps2)(CStreamFileProps *props); - #endif }; -class CStdInFileStream: - public ISequentialInStream, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP - virtual ~CStdInFileStream() {} - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); +Z7_CLASS_IMP_NOQIB_1( + CStdInFileStream + , ISequentialInStream +) }; -class COutFileStream: - public IOutStream, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_COM_1( + COutFileStream + , IOutStream +) + Z7_IFACE_COM7_IMP(ISequentialOutStream) public: - #ifdef USE_WIN_FILE + NWindows::NFile::NIO::COutFile File; - #else - NC::NFile::NIO::COutFile File; - #endif - virtual ~COutFileStream() {} + bool Create(CFSTR fileName, bool createAlways) { ProcessedSize = 0; @@ -131,36 +154,33 @@ public: UInt64 ProcessedSize; - #ifdef USE_WIN_FILE - bool SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime) + bool SetTime(const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime) { return File.SetTime(cTime, aTime, mTime); } - bool SetMTime(const FILETIME *mTime) { return File.SetMTime(mTime); } - #endif + bool SetMTime(const CFiTime *mTime) { return File.SetMTime(mTime); } - - MY_UNKNOWN_IMP1(IOutStream) - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - STDMETHOD(SetSize)(UInt64 newSize); + bool SeekToBegin_bool() + { + #ifdef Z7_FILE_STREAMS_USE_WIN_FILE + return File.SeekToBegin(); + #else + return File.seekToBegin() == 0; + #endif + } HRESULT GetSize(UInt64 *size); }; -class CStdOutFileStream: - public ISequentialOutStream, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_NOQIB_1( + CStdOutFileStream + , ISequentialOutStream +) UInt64 _size; public: - MY_UNKNOWN_IMP - UInt64 GetSize() const { return _size; } CStdOutFileStream(): _size(0) {} - virtual ~CStdOutFileStream() {} - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); }; #endif diff --git a/3rdparty/lzma/CPP/7zip/Common/FilterCoder.cpp b/3rdparty/lzma/CPP/7zip/Common/FilterCoder.cpp index 4f3ae4e7dcf..8d7e0dccfe5 100644 --- a/3rdparty/lzma/CPP/7zip/Common/FilterCoder.cpp +++ b/3rdparty/lzma/CPP/7zip/Common/FilterCoder.cpp @@ -2,11 +2,30 @@ #include "StdAfx.h" +// #include <stdio.h> + #include "../../Common/Defs.h" #include "FilterCoder.h" #include "StreamUtils.h" +#ifdef _WIN32 + #define alignedMidBuffer_Alloc g_MidAlloc +#else + #define alignedMidBuffer_Alloc g_AlignedAlloc +#endif + +CAlignedMidBuffer::~CAlignedMidBuffer() +{ + ISzAlloc_Free(&alignedMidBuffer_Alloc, _buf); +} + +void CAlignedMidBuffer::AllocAligned(size_t size) +{ + ISzAlloc_Free(&alignedMidBuffer_Alloc, _buf); + _buf = (Byte *)ISzAlloc_Alloc(&alignedMidBuffer_Alloc, size); +} + /* AES filters need 16-bytes alignment for HARDWARE-AES instructions. So we call IFilter::Filter(, size), where (size != 16 * N) only for last data block. @@ -16,13 +35,17 @@ Some filters (BCJ and others) don't process data at the end of stream in some cases. So the encoder and decoder write such last bytes without change. + + Most filters process all data, if we send aligned size to filter. + But BCJ filter can process up 4 bytes less than sent size. + And ARMT filter can process 2 bytes less than sent size. */ -static const UInt32 kBufSize = 1 << 20; +static const UInt32 kBufSize = 1 << 21; -STDMETHODIMP CFilterCoder::SetInBufSize(UInt32 , UInt32 size) { _inBufSize = size; return S_OK; } -STDMETHODIMP CFilterCoder::SetOutBufSize(UInt32 , UInt32 size) { _outBufSize = size; return S_OK; } +Z7_COM7F_IMF(CFilterCoder::SetInBufSize(UInt32 , UInt32 size)) { _inBufSize = size; return S_OK; } +Z7_COM7F_IMF(CFilterCoder::SetOutBufSize(UInt32 , UInt32 size)) { _outBufSize = size; return S_OK; } HRESULT CFilterCoder::Alloc() { @@ -34,9 +57,10 @@ HRESULT CFilterCoder::Alloc() size &= ~(UInt32)(kMinSize - 1); if (size < kMinSize) size = kMinSize; + // size = (1 << 12); // + 117; // for debug if (!_buf || _bufSize != size) { - AllocAlignedMask(size, 16 - 1); + AllocAligned(size); if (!_buf) return E_OUTOFMEMORY; _bufSize = size; @@ -46,7 +70,7 @@ HRESULT CFilterCoder::Alloc() HRESULT CFilterCoder::Init_and_Alloc() { - RINOK(Filter->Init()); + RINOK(Filter->Init()) return Alloc(); } @@ -55,78 +79,198 @@ CFilterCoder::CFilterCoder(bool encodeMode): _inBufSize(kBufSize), _outBufSize(kBufSize), _encodeMode(encodeMode), - _outSizeIsDefined(false), + _outSize_Defined(false), _outSize(0), _nowPos64(0) {} -CFilterCoder::~CFilterCoder() -{ -} -STDMETHODIMP CFilterCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress) +Z7_COM7F_IMF(CFilterCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)) { - RINOK(Init_and_Alloc()); - + RINOK(Init_and_Alloc()) + + /* + It's expected that BCJ/ARMT filter can process up to 4 bytes less + than sent data size. For such BCJ/ARMT cases with non-filtered data we: + - write some filtered data to output stream + - move non-written data (filtered and non-filtered data) to start of buffer + - read more new data from input stream to position after end of non-filtered data + - call Filter() for concatenated data in buffer. + + For all cases, even for cases with partial filtering (BCJ/ARMT), + we try to keep real/virtual alignment for all operations + (memmove, Read(), Filter(), Write()). + We use (kAlignSize=64) alignmnent that is larger than (16-bytes) + required for AES filter alignment. + + AES-CBC uses 16-bytes blocks, that is simple case for processing here, + if we call Filter() for aligned size for all calls except of last call (last block). + And now there are no filters that use blocks with non-power2 size, + but we try to support such non-power2 filters too here at Code(). + */ + + UInt64 prev = 0; UInt64 nowPos64 = 0; bool inputFinished = false; - UInt32 pos = 0; + UInt32 readPos = 0; + UInt32 filterPos = 0; while (!outSize || nowPos64 < *outSize) { - UInt32 endPos = pos; - + HRESULT hres = S_OK; if (!inputFinished) { - size_t processedSize = _bufSize - pos; - RINOK(ReadStream(inStream, _buf + pos, &processedSize)); - endPos = pos + (UInt32)processedSize; - inputFinished = (endPos != _bufSize); + size_t processedSize = _bufSize - readPos; + /* for AES filters we need at least max(16, kAlignSize) bytes in buffer. + But we try to read full buffer to reduce the number of Filter() and Write() calls. + */ + hres = ReadStream(inStream, _buf + readPos, &processedSize); + readPos += (UInt32)processedSize; + inputFinished = (readPos != _bufSize); + if (hres != S_OK) + { + // do we need to stop encoding after reading error? + // if (_encodeMode) return hres; + inputFinished = true; + } } - pos = Filter->Filter(_buf, endPos); - - if (pos > endPos) + if (readPos == 0) + return hres; + + /* we set (needMoreInput = true), if it's block-filter (like AES-CBC) + that needs more data for current block filtering: + We read full input buffer with Read(), and _bufSize is aligned, + So the possible cases when we set (needMoreInput = true) are: + 1) decode : filter needs more data after the end of input stream. + another cases are possible for non-power2-block-filter, + because buffer size is not aligned for filter_non_power2_block_size: + 2) decode/encode : filter needs more data from non-finished input stream + 3) encode : filter needs more space for zeros after the end of input stream + */ + bool needMoreInput = false; + + while (readPos != filterPos) { - // AES - if (!inputFinished || pos > _bufSize) - return E_FAIL; - if (!_encodeMode) - return S_FALSE; - - do - _buf[endPos] = 0; - while (++endPos != pos); - - if (pos != Filter->Filter(_buf, pos)) - return E_FAIL; + /* Filter() is allowed to process part of data. + Here we use the loop to filter as max as possible. + when we call Filter(data, size): + if (size < 16), AES-CTR filter uses internal 16-byte buffer. + new (since v23.00) AES-CTR filter allows (size < 16) for non-last block, + but it will work less efficiently than calls with aligned (size). + We still support old (before v23.00) AES-CTR filters here. + We have aligned (size) for AES-CTR, if it's not last block. + We have aligned (readPos) for any filter, if (!inputFinished). + We also meet the requirements for (data) pointer in Filter() call: + { + (virtual_stream_offset % aligment_size) == (data_ptr % aligment_size) + (aligment_size == 2^N) + (aligment_size >= 16) + } + */ + const UInt32 cur = Filter->Filter(_buf + filterPos, readPos - filterPos); + if (cur == 0) + break; + const UInt32 f = filterPos + cur; + if (cur > readPos - filterPos) + { + // AES-CBC + if (hres != S_OK) + break; + + if (!_encodeMode + || cur > _bufSize - filterPos + || !inputFinished) + { + /* (cur > _bufSize - filterPos) is unexpected for AES filter, if _bufSize is multiply of 16. + But we support this case, if some future filter will use block with non-power2-size. + */ + needMoreInput = true; + break; + } + + /* (_encodeMode && inputFinished). + We add zero bytes as pad in current block after the end of read data. */ + Byte *buf = _buf; + do + buf[readPos] = 0; + while (++readPos != f); + // (readPos) now is (size_of_real_input_data + size_of_zero_pad) + if (cur != Filter->Filter(buf + filterPos, cur)) + return E_FAIL; + } + filterPos = f; } - if (endPos == 0) - return S_OK; + UInt32 size = filterPos; + if (hres == S_OK) + { + /* If we need more Read() or Filter() calls, then we need to Write() + some data and move unwritten data to get additional space in buffer. + We try to keep alignment for data moves, Read(), Filter() and Write() calls. + */ + const UInt32 kAlignSize = 1 << 6; + const UInt32 alignedFiltered = filterPos & ~(kAlignSize - 1); + if (inputFinished) + { + if (!needMoreInput) + size = readPos; // for risc/bcj filters in last block we write data after filterPos. + else if (_encodeMode) + size = alignedFiltered; // for non-power2-block-encode-filter + } + else + size = alignedFiltered; + } - UInt32 size = (pos != 0 ? pos : endPos); - if (outSize) { - UInt64 remSize = *outSize - nowPos64; - if (size > remSize) - size = (UInt32)remSize; + UInt32 writeSize = size; + if (outSize) + { + const UInt64 rem = *outSize - nowPos64; + if (writeSize > rem) + writeSize = (UInt32)rem; + } + RINOK(WriteStream(outStream, _buf, writeSize)) + nowPos64 += writeSize; } - - RINOK(WriteStream(outStream, _buf, size)); - nowPos64 += size; - if (pos == 0) - return S_OK; + if (hres != S_OK) + return hres; - if (progress) - RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64)); + if (inputFinished) + { + if (readPos == size) + return hres; + if (!_encodeMode) + { + // block-decode-filter (AES-CBS) has non-full last block + // we don't want unaligned data move for more iterations with this error case. + return S_FALSE; + } + } - UInt32 i = 0; - while (pos < endPos) - _buf[i++] = _buf[pos++]; - pos = i; + if (size == 0) + { + // it's unexpected that we have no any move in this iteration. + return E_FAIL; + } + // if (size != 0) + { + if (filterPos < size) + return E_FAIL; // filterPos = 0; else + filterPos -= size; + readPos -= size; + if (readPos != 0) + memmove(_buf, _buf + size, readPos); + } + // printf("\nnowPos64=%x, readPos=%x, filterPos=%x\n", (unsigned)nowPos64, (unsigned)readPos, (unsigned)filterPos); + + if (progress && (nowPos64 - prev) >= (1 << 22)) + { + prev = nowPos64; + RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64)) + } } return S_OK; @@ -136,13 +280,13 @@ STDMETHODIMP CFilterCoder::Code(ISequentialInStream *inStream, ISequentialOutStr // ---------- Write to Filter ---------- -STDMETHODIMP CFilterCoder::SetOutStream(ISequentialOutStream *outStream) +Z7_COM7F_IMF(CFilterCoder::SetOutStream(ISequentialOutStream *outStream)) { _outStream = outStream; return S_OK; } -STDMETHODIMP CFilterCoder::ReleaseOutStream() +Z7_COM7F_IMF(CFilterCoder::ReleaseOutStream()) { _outStream.Release(); return S_OK; @@ -153,9 +297,9 @@ HRESULT CFilterCoder::Flush2() while (_convSize != 0) { UInt32 num = _convSize; - if (_outSizeIsDefined) + if (_outSize_Defined) { - UInt64 rem = _outSize - _nowPos64; + const UInt64 rem = _outSize - _nowPos64; if (num > rem) num = (UInt32)rem; if (num == 0) @@ -163,21 +307,23 @@ HRESULT CFilterCoder::Flush2() } UInt32 processed = 0; - HRESULT res = _outStream->Write(_buf + _convPos, num, &processed); + const HRESULT res = _outStream->Write(_buf + _convPos, num, &processed); if (processed == 0) return res != S_OK ? res : E_FAIL; _convPos += processed; _convSize -= processed; _nowPos64 += processed; - RINOK(res); + RINOK(res) } - if (_convPos != 0) + const UInt32 convPos = _convPos; + if (convPos != 0) { - UInt32 num = _bufPos - _convPos; + const UInt32 num = _bufPos - convPos; + Byte *buf = _buf; for (UInt32 i = 0; i < num; i++) - _buf[i] = _buf[_convPos + i]; + buf[i] = buf[convPos + i]; _bufPos = num; _convPos = 0; } @@ -185,14 +331,14 @@ HRESULT CFilterCoder::Flush2() return S_OK; } -STDMETHODIMP CFilterCoder::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CFilterCoder::Write(const void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; while (size != 0) { - RINOK(Flush2()); + RINOK(Flush2()) // _convSize is 0 // _convPos is 0 @@ -227,20 +373,22 @@ STDMETHODIMP CFilterCoder::Write(const void *data, UInt32 size, UInt32 *processe return S_OK; } -STDMETHODIMP CFilterCoder::OutStreamFinish() +Z7_COM7F_IMF(CFilterCoder::OutStreamFinish()) { for (;;) { - RINOK(Flush2()); + RINOK(Flush2()) if (_bufPos == 0) break; - _convSize = Filter->Filter(_buf, _bufPos); - if (_convSize == 0) - _convSize = _bufPos; - else if (_convSize > _bufPos) + const UInt32 convSize = Filter->Filter(_buf, _bufPos); + _convSize = convSize; + UInt32 bufPos = _bufPos; + if (convSize == 0) + _convSize = bufPos; + else if (convSize > bufPos) { // AES - if (_convSize > _bufSize) + if (convSize > _bufSize) { _convSize = 0; return E_FAIL; @@ -250,9 +398,11 @@ STDMETHODIMP CFilterCoder::OutStreamFinish() _convSize = 0; return S_FALSE; } - for (; _bufPos < _convSize; _bufPos++) - _buf[_bufPos] = 0; - _convSize = Filter->Filter(_buf, _bufPos); + Byte *buf = _buf; + for (; bufPos < convSize; bufPos++) + buf[bufPos] = 0; + _bufPos = bufPos; + _convSize = Filter->Filter(_buf, bufPos); if (_convSize != _bufPos) return E_FAIL; } @@ -267,7 +417,7 @@ STDMETHODIMP CFilterCoder::OutStreamFinish() // ---------- Init functions ---------- -STDMETHODIMP CFilterCoder::InitEncoder() +Z7_COM7F_IMF(CFilterCoder::InitEncoder()) { InitSpecVars(); return Init_and_Alloc(); @@ -279,33 +429,33 @@ HRESULT CFilterCoder::Init_NoSubFilterInit() return Alloc(); } -STDMETHODIMP CFilterCoder::SetOutStreamSize(const UInt64 *outSize) +Z7_COM7F_IMF(CFilterCoder::SetOutStreamSize(const UInt64 *outSize)) { InitSpecVars(); if (outSize) { _outSize = *outSize; - _outSizeIsDefined = true; + _outSize_Defined = true; } return Init_and_Alloc(); } // ---------- Read from Filter ---------- -STDMETHODIMP CFilterCoder::SetInStream(ISequentialInStream *inStream) +Z7_COM7F_IMF(CFilterCoder::SetInStream(ISequentialInStream *inStream)) { _inStream = inStream; return S_OK; } -STDMETHODIMP CFilterCoder::ReleaseInStream() +Z7_COM7F_IMF(CFilterCoder::ReleaseInStream()) { _inStream.Release(); return S_OK; } -STDMETHODIMP CFilterCoder::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CFilterCoder::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -316,9 +466,9 @@ STDMETHODIMP CFilterCoder::Read(void *data, UInt32 size, UInt32 *processedSize) { if (size > _convSize) size = _convSize; - if (_outSizeIsDefined) + if (_outSize_Defined) { - UInt64 rem = _outSize - _nowPos64; + const UInt64 rem = _outSize - _nowPos64; if (size > rem) size = (UInt32)rem; } @@ -331,46 +481,51 @@ STDMETHODIMP CFilterCoder::Read(void *data, UInt32 size, UInt32 *processedSize) break; } - if (_convPos != 0) + const UInt32 convPos = _convPos; + if (convPos != 0) { - UInt32 num = _bufPos - _convPos; + const UInt32 num = _bufPos - convPos; + Byte *buf = _buf; for (UInt32 i = 0; i < num; i++) - _buf[i] = _buf[_convPos + i]; + buf[i] = buf[convPos + i]; _bufPos = num; _convPos = 0; } { size_t readSize = _bufSize - _bufPos; - HRESULT res = ReadStream(_inStream, _buf + _bufPos, &readSize); + const HRESULT res = ReadStream(_inStream, _buf + _bufPos, &readSize); _bufPos += (UInt32)readSize; - RINOK(res); + RINOK(res) } - _convSize = Filter->Filter(_buf, _bufPos); + const UInt32 convSize = Filter->Filter(_buf, _bufPos); + _convSize = convSize; - if (_convSize == 0) + UInt32 bufPos = _bufPos; + + if (convSize == 0) { - if (_bufPos == 0) + if (bufPos == 0) break; // BCJ - _convSize = _bufPos; + _convSize = bufPos; continue; } - if (_convSize > _bufPos) + if (convSize > bufPos) { // AES - if (_convSize > _bufSize) + if (convSize > _bufSize) return E_FAIL; if (!_encodeMode) return S_FALSE; - + Byte *buf = _buf; do - _buf[_bufPos] = 0; - while (++_bufPos != _convSize); - - _convSize = Filter->Filter(_buf, _convSize); + buf[bufPos] = 0; + while (++bufPos != convSize); + _bufPos = bufPos; + _convSize = Filter->Filter(_buf, convSize); if (_convSize != _bufPos) return E_FAIL; } @@ -380,39 +535,43 @@ STDMETHODIMP CFilterCoder::Read(void *data, UInt32 size, UInt32 *processedSize) } -#ifndef _NO_CRYPTO +#ifndef Z7_NO_CRYPTO -STDMETHODIMP CFilterCoder::CryptoSetPassword(const Byte *data, UInt32 size) - { return _SetPassword->CryptoSetPassword(data, size); } +Z7_COM7F_IMF(CFilterCoder::CryptoSetPassword(const Byte *data, UInt32 size)) + { return _setPassword->CryptoSetPassword(data, size); } -STDMETHODIMP CFilterCoder::SetKey(const Byte *data, UInt32 size) - { return _CryptoProperties->SetKey(data, size); } +Z7_COM7F_IMF(CFilterCoder::SetKey(const Byte *data, UInt32 size)) + { return _cryptoProperties->SetKey(data, size); } -STDMETHODIMP CFilterCoder::SetInitVector(const Byte *data, UInt32 size) - { return _CryptoProperties->SetInitVector(data, size); } +Z7_COM7F_IMF(CFilterCoder::SetInitVector(const Byte *data, UInt32 size)) + { return _cryptoProperties->SetInitVector(data, size); } #endif -#ifndef EXTRACT_ONLY +#ifndef Z7_EXTRACT_ONLY + +Z7_COM7F_IMF(CFilterCoder::SetCoderProperties(const PROPID *propIDs, + const PROPVARIANT *properties, UInt32 numProperties)) + { return _setCoderProperties->SetCoderProperties(propIDs, properties, numProperties); } -STDMETHODIMP CFilterCoder::SetCoderProperties(const PROPID *propIDs, - const PROPVARIANT *properties, UInt32 numProperties) - { return _SetCoderProperties->SetCoderProperties(propIDs, properties, numProperties); } +Z7_COM7F_IMF(CFilterCoder::WriteCoderProperties(ISequentialOutStream *outStream)) + { return _writeCoderProperties->WriteCoderProperties(outStream); } -STDMETHODIMP CFilterCoder::WriteCoderProperties(ISequentialOutStream *outStream) - { return _WriteCoderProperties->WriteCoderProperties(outStream); } +Z7_COM7F_IMF(CFilterCoder::SetCoderPropertiesOpt(const PROPID *propIDs, + const PROPVARIANT *properties, UInt32 numProperties)) + { return _setCoderPropertiesOpt->SetCoderPropertiesOpt(propIDs, properties, numProperties); } /* -STDMETHODIMP CFilterCoder::ResetSalt() - { return _CryptoResetSalt->ResetSalt(); } +Z7_COM7F_IMF(CFilterCoder::ResetSalt() + { return _cryptoResetSalt->ResetSalt(); } */ -STDMETHODIMP CFilterCoder::ResetInitVector() - { return _CryptoResetInitVector->ResetInitVector(); } +Z7_COM7F_IMF(CFilterCoder::ResetInitVector()) + { return _cryptoResetInitVector->ResetInitVector(); } #endif -STDMETHODIMP CFilterCoder::SetDecoderProperties2(const Byte *data, UInt32 size) - { return _SetDecoderProperties2->SetDecoderProperties2(data, size); } +Z7_COM7F_IMF(CFilterCoder::SetDecoderProperties2(const Byte *data, UInt32 size)) + { return _setDecoderProperties2->SetDecoderProperties2(data, size); } diff --git a/3rdparty/lzma/CPP/7zip/Common/FilterCoder.h b/3rdparty/lzma/CPP/7zip/Common/FilterCoder.h index 224ff2ca459..3a588fd5228 100644 --- a/3rdparty/lzma/CPP/7zip/Common/FilterCoder.h +++ b/3rdparty/lzma/CPP/7zip/Common/FilterCoder.h @@ -1,62 +1,33 @@ // FilterCoder.h -#ifndef __FILTER_CODER_H -#define __FILTER_CODER_H +#ifndef ZIP7_INC_FILTER_CODER_H +#define ZIP7_INC_FILTER_CODER_H #include "../../../C/Alloc.h" #include "../../Common/MyCom.h" #include "../ICoder.h" -#ifndef _NO_CRYPTO +#ifndef Z7_NO_CRYPTO #include "../IPassword.h" #endif -#define MY_QUERYINTERFACE_ENTRY_AG(i, sub0, sub) else if (iid == IID_ ## i) \ +#define Z7_COM_QI_ENTRY_AG(i, sub0, sub) else if (iid == IID_ ## i) \ { if (!sub) RINOK(sub0->QueryInterface(IID_ ## i, (void **)&sub)) \ *outObject = (void *)(i *)this; } struct CAlignedMidBuffer { - #ifdef _WIN32 - Byte *_buf; CAlignedMidBuffer(): _buf(NULL) {} - ~CAlignedMidBuffer() { ::MidFree(_buf); } - - void AllocAlignedMask(size_t size, size_t) - { - ::MidFree(_buf); - _buf = (Byte *)::MidAlloc(size); - } - - #else - - Byte *_bufBase; - Byte *_buf; - - CAlignedMidBuffer(): _bufBase(NULL), _buf(NULL) {} - ~CAlignedMidBuffer() { ::MidFree(_bufBase); } - - void AllocAlignedMask(size_t size, size_t alignMask) - { - ::MidFree(_bufBase); - _buf = NULL; - _bufBase = (Byte *)::MidAlloc(size + alignMask); - - if (_bufBase) - { - // _buf = (Byte *)(((uintptr_t)_bufBase + alignMask) & ~(uintptr_t)alignMask); - _buf = (Byte *)(((ptrdiff_t)_bufBase + alignMask) & ~(ptrdiff_t)alignMask); - } - } - - #endif + ~CAlignedMidBuffer(); + void AllocAligned(size_t size); }; -class CFilterCoder: + +class CFilterCoder Z7_final : public ICompressCoder, public ICompressSetOutStreamSize, @@ -71,14 +42,15 @@ class CFilterCoder: public ICompressSetBufSize, - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO public ICryptoSetPassword, public ICryptoProperties, #endif - #ifndef EXTRACT_ONLY + #ifndef Z7_EXTRACT_ONLY public ICompressSetCoderProperties, public ICompressWriteCoderProperties, + public ICompressSetCoderPropertiesOpt, // public ICryptoResetSalt, public ICryptoResetInitVector, #endif @@ -92,7 +64,7 @@ class CFilterCoder: UInt32 _outBufSize; bool _encodeMode; - bool _outSizeIsDefined; + bool _outSize_Defined; UInt64 _outSize; UInt64 _nowPos64; @@ -108,7 +80,7 @@ class CFilterCoder: _convPos = 0; _convSize = 0; - _outSizeIsDefined = false; + _outSize_Defined = false; _outSize = 0; _nowPos64 = 0; } @@ -117,108 +89,111 @@ class CFilterCoder: HRESULT Init_and_Alloc(); HRESULT Flush2(); - #ifndef _NO_CRYPTO - CMyComPtr<ICryptoSetPassword> _SetPassword; - CMyComPtr<ICryptoProperties> _CryptoProperties; + #ifndef Z7_NO_CRYPTO + CMyComPtr<ICryptoSetPassword> _setPassword; + CMyComPtr<ICryptoProperties> _cryptoProperties; #endif - #ifndef EXTRACT_ONLY - CMyComPtr<ICompressSetCoderProperties> _SetCoderProperties; - CMyComPtr<ICompressWriteCoderProperties> _WriteCoderProperties; - // CMyComPtr<ICryptoResetSalt> _CryptoResetSalt; - CMyComPtr<ICryptoResetInitVector> _CryptoResetInitVector; + #ifndef Z7_EXTRACT_ONLY + CMyComPtr<ICompressSetCoderProperties> _setCoderProperties; + CMyComPtr<ICompressWriteCoderProperties> _writeCoderProperties; + CMyComPtr<ICompressSetCoderPropertiesOpt> _setCoderPropertiesOpt; + // CMyComPtr<ICryptoResetSalt> _cryptoResetSalt; + CMyComPtr<ICryptoResetInitVector> _cryptoResetInitVector; #endif - CMyComPtr<ICompressSetDecoderProperties2> _SetDecoderProperties2; + CMyComPtr<ICompressSetDecoderProperties2> _setDecoderProperties2; public: CMyComPtr<ICompressFilter> Filter; CFilterCoder(bool encodeMode); - ~CFilterCoder(); - class C_InStream_Releaser + struct C_InStream_Releaser { - public: CFilterCoder *FilterCoder; C_InStream_Releaser(): FilterCoder(NULL) {} ~C_InStream_Releaser() { if (FilterCoder) FilterCoder->ReleaseInStream(); } }; - class C_OutStream_Releaser + struct C_OutStream_Releaser { - public: CFilterCoder *FilterCoder; C_OutStream_Releaser(): FilterCoder(NULL) {} ~C_OutStream_Releaser() { if (FilterCoder) FilterCoder->ReleaseOutStream(); } }; - MY_QUERYINTERFACE_BEGIN2(ICompressCoder) + struct C_Filter_Releaser + { + CFilterCoder *FilterCoder; + C_Filter_Releaser(): FilterCoder(NULL) {} + ~C_Filter_Releaser() { if (FilterCoder) FilterCoder->Filter.Release(); } + }; + +private: + Z7_COM_QI_BEGIN2(ICompressCoder) - MY_QUERYINTERFACE_ENTRY(ICompressSetOutStreamSize) - MY_QUERYINTERFACE_ENTRY(ICompressInitEncoder) + Z7_COM_QI_ENTRY(ICompressSetOutStreamSize) + Z7_COM_QI_ENTRY(ICompressInitEncoder) - MY_QUERYINTERFACE_ENTRY(ICompressSetInStream) - MY_QUERYINTERFACE_ENTRY(ISequentialInStream) + Z7_COM_QI_ENTRY(ICompressSetInStream) + Z7_COM_QI_ENTRY(ISequentialInStream) - MY_QUERYINTERFACE_ENTRY(ICompressSetOutStream) - MY_QUERYINTERFACE_ENTRY(ISequentialOutStream) - MY_QUERYINTERFACE_ENTRY(IOutStreamFinish) + Z7_COM_QI_ENTRY(ICompressSetOutStream) + Z7_COM_QI_ENTRY(ISequentialOutStream) + Z7_COM_QI_ENTRY(IOutStreamFinish) - MY_QUERYINTERFACE_ENTRY(ICompressSetBufSize) + Z7_COM_QI_ENTRY(ICompressSetBufSize) - #ifndef _NO_CRYPTO - MY_QUERYINTERFACE_ENTRY_AG(ICryptoSetPassword, Filter, _SetPassword) - MY_QUERYINTERFACE_ENTRY_AG(ICryptoProperties, Filter, _CryptoProperties) + #ifndef Z7_NO_CRYPTO + Z7_COM_QI_ENTRY_AG(ICryptoSetPassword, Filter, _setPassword) + Z7_COM_QI_ENTRY_AG(ICryptoProperties, Filter, _cryptoProperties) #endif - #ifndef EXTRACT_ONLY - MY_QUERYINTERFACE_ENTRY_AG(ICompressSetCoderProperties, Filter, _SetCoderProperties) - MY_QUERYINTERFACE_ENTRY_AG(ICompressWriteCoderProperties, Filter, _WriteCoderProperties) - // MY_QUERYINTERFACE_ENTRY_AG(ICryptoResetSalt, Filter, _CryptoResetSalt) - MY_QUERYINTERFACE_ENTRY_AG(ICryptoResetInitVector, Filter, _CryptoResetInitVector) + #ifndef Z7_EXTRACT_ONLY + Z7_COM_QI_ENTRY_AG(ICompressSetCoderProperties, Filter, _setCoderProperties) + Z7_COM_QI_ENTRY_AG(ICompressWriteCoderProperties, Filter, _writeCoderProperties) + Z7_COM_QI_ENTRY_AG(ICompressSetCoderPropertiesOpt, Filter, _setCoderPropertiesOpt) + // Z7_COM_QI_ENTRY_AG(ICryptoResetSalt, Filter, _cryptoResetSalt) + Z7_COM_QI_ENTRY_AG(ICryptoResetInitVector, Filter, _cryptoResetInitVector) #endif - MY_QUERYINTERFACE_ENTRY_AG(ICompressSetDecoderProperties2, Filter, _SetDecoderProperties2) - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE + Z7_COM_QI_ENTRY_AG(ICompressSetDecoderProperties2, Filter, _setDecoderProperties2) + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE +public: + Z7_IFACE_COM7_IMP(ICompressCoder) + Z7_IFACE_COM7_IMP(ICompressSetOutStreamSize) + Z7_IFACE_COM7_IMP(ICompressInitEncoder) + Z7_IFACE_COM7_IMP(ICompressSetInStream) +private: + Z7_IFACE_COM7_IMP(ISequentialInStream) +public: + Z7_IFACE_COM7_IMP(ICompressSetOutStream) +private: + Z7_IFACE_COM7_IMP(ISequentialOutStream) +public: + Z7_IFACE_COM7_IMP(IOutStreamFinish) +private: - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - - STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); - STDMETHOD(InitEncoder)(); - - STDMETHOD(SetInStream)(ISequentialInStream *inStream); - STDMETHOD(ReleaseInStream)(); - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - - STDMETHOD(SetOutStream)(ISequentialOutStream *outStream); - STDMETHOD(ReleaseOutStream)(); - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(OutStreamFinish)(); - - STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size); - STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size); + Z7_IFACE_COM7_IMP(ICompressSetBufSize) - #ifndef _NO_CRYPTO - STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size); - - STDMETHOD(SetKey)(const Byte *data, UInt32 size); - STDMETHOD(SetInitVector)(const Byte *data, UInt32 size); + #ifndef Z7_NO_CRYPTO + Z7_IFACE_COM7_IMP(ICryptoSetPassword) + Z7_IFACE_COM7_IMP(ICryptoProperties) #endif - #ifndef EXTRACT_ONLY - STDMETHOD(SetCoderProperties)(const PROPID *propIDs, - const PROPVARIANT *properties, UInt32 numProperties); - STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream); - // STDMETHOD(ResetSalt)(); - STDMETHOD(ResetInitVector)(); + #ifndef Z7_EXTRACT_ONLY + Z7_IFACE_COM7_IMP(ICompressSetCoderProperties) + Z7_IFACE_COM7_IMP(ICompressWriteCoderProperties) + Z7_IFACE_COM7_IMP(ICompressSetCoderPropertiesOpt) + // Z7_IFACE_COM7_IMP(ICryptoResetSalt) + Z7_IFACE_COM7_IMP(ICryptoResetInitVector) #endif - STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); - +public: + Z7_IFACE_COM7_IMP(ICompressSetDecoderProperties2) HRESULT Init_NoSubFilterInit(); }; diff --git a/3rdparty/lzma/CPP/7zip/Common/InBuffer.cpp b/3rdparty/lzma/CPP/7zip/Common/InBuffer.cpp index 133d95b3885..b0f222c2621 100644 --- a/3rdparty/lzma/CPP/7zip/Common/InBuffer.cpp +++ b/3rdparty/lzma/CPP/7zip/Common/InBuffer.cpp @@ -7,10 +7,10 @@ #include "InBuffer.h" CInBufferBase::CInBufferBase() throw(): - _buf(0), - _bufLim(0), - _bufBase(0), - _stream(0), + _buf(NULL), + _bufLim(NULL), + _bufBase(NULL), + _stream(NULL), _processedSize(0), _bufSize(0), _wasFinished(false), @@ -22,18 +22,18 @@ bool CInBuffer::Create(size_t bufSize) throw() const unsigned kMinBlockSize = 1; if (bufSize < kMinBlockSize) bufSize = kMinBlockSize; - if (_bufBase != 0 && _bufSize == bufSize) + if (_bufBase != NULL && _bufSize == bufSize) return true; Free(); _bufSize = bufSize; _bufBase = (Byte *)::MidAlloc(bufSize); - return (_bufBase != 0); + return (_bufBase != NULL); } void CInBuffer::Free() throw() { ::MidFree(_bufBase); - _bufBase = 0; + _bufBase = NULL; } void CInBufferBase::Init() throw() @@ -42,7 +42,7 @@ void CInBufferBase::Init() throw() _buf = _bufBase; _bufLim = _buf; _wasFinished = false; - #ifdef _NO_EXCEPTIONS + #ifdef Z7_NO_EXCEPTIONS ErrorCode = S_OK; #endif NumExtraBytes = 0; @@ -50,19 +50,19 @@ void CInBufferBase::Init() throw() bool CInBufferBase::ReadBlock() { - #ifdef _NO_EXCEPTIONS + #ifdef Z7_NO_EXCEPTIONS if (ErrorCode != S_OK) return false; #endif if (_wasFinished) return false; - _processedSize += (_buf - _bufBase); + _processedSize += (size_t)(_buf - _bufBase); _buf = _bufBase; _bufLim = _bufBase; UInt32 processed; // FIX_ME: we can improve it to support (_bufSize >= (1 << 32)) - HRESULT result = _stream->Read(_bufBase, (UInt32)_bufSize, &processed); - #ifdef _NO_EXCEPTIONS + const HRESULT result = _stream->Read(_bufBase, (UInt32)_bufSize, &processed); + #ifdef Z7_NO_EXCEPTIONS ErrorCode = result; #else if (result != S_OK) @@ -77,7 +77,8 @@ bool CInBufferBase::ReadByte_FromNewBlock(Byte &b) { if (!ReadBlock()) { - NumExtraBytes++; + // 22.00: we don't increment (NumExtraBytes) here + // NumExtraBytes++; b = 0xFF; return false; } @@ -97,6 +98,33 @@ Byte CInBufferBase::ReadByte_FromNewBlock() size_t CInBufferBase::ReadBytes(Byte *buf, size_t size) { + size_t num = 0; + for (;;) + { + const size_t rem = (size_t)(_bufLim - _buf); + if (size <= rem) + { + if (size != 0) + { + memcpy(buf, _buf, size); + _buf += size; + num += size; + } + return num; + } + if (rem != 0) + { + memcpy(buf, _buf, rem); + _buf += rem; + buf += rem; + num += rem; + size -= rem; + } + if (!ReadBlock()) + return num; + } + + /* if ((size_t)(_bufLim - _buf) >= size) { const Byte *src = _buf; @@ -113,6 +141,7 @@ size_t CInBufferBase::ReadBytes(Byte *buf, size_t size) buf[i] = *_buf++; } return size; + */ } size_t CInBufferBase::Skip(size_t size) @@ -120,7 +149,7 @@ size_t CInBufferBase::Skip(size_t size) size_t processed = 0; for (;;) { - size_t rem = (_bufLim - _buf); + const size_t rem = (size_t)(_bufLim - _buf); if (rem >= size) { _buf += size; diff --git a/3rdparty/lzma/CPP/7zip/Common/InBuffer.h b/3rdparty/lzma/CPP/7zip/Common/InBuffer.h index 4b8662bb9d5..3aaf797a589 100644 --- a/3rdparty/lzma/CPP/7zip/Common/InBuffer.h +++ b/3rdparty/lzma/CPP/7zip/Common/InBuffer.h @@ -1,12 +1,12 @@ // InBuffer.h -#ifndef __IN_BUFFER_H -#define __IN_BUFFER_H +#ifndef ZIP7_INC_IN_BUFFER_H +#define ZIP7_INC_IN_BUFFER_H #include "../../Common/MyException.h" #include "../IStream.h" -#ifndef _NO_EXCEPTIONS +#ifndef Z7_NO_EXCEPTIONS struct CInBufferException: public CSystemException { CInBufferException(HRESULT errorCode): CSystemException(errorCode) {} @@ -31,15 +31,23 @@ protected: Byte ReadByte_FromNewBlock(); public: - #ifdef _NO_EXCEPTIONS + #ifdef Z7_NO_EXCEPTIONS HRESULT ErrorCode; #endif UInt32 NumExtraBytes; CInBufferBase() throw(); - UInt64 GetStreamSize() const { return _processedSize + (_buf - _bufBase); } - UInt64 GetProcessedSize() const { return _processedSize + NumExtraBytes + (_buf - _bufBase); } + // the size of portion of data in real stream that was already read from this object + // it doesn't include unused data in buffer + // it doesn't include virtual Extra bytes after the end of real stream data + UInt64 GetStreamSize() const { return _processedSize + (size_t)(_buf - _bufBase); } + + // the size of virtual data that was read from this object + // it doesn't include unused data in buffers + // it includes any virtual Extra bytes after the end of real data + UInt64 GetProcessedSize() const { return _processedSize + NumExtraBytes + (size_t)(_buf - _bufBase); } + bool WasFinished() const { return _wasFinished; } void SetStream(ISequentialInStream *stream) { _stream = stream; } @@ -52,14 +60,15 @@ public: _buf = buf + pos; _bufLim = buf + end; _wasFinished = false; - #ifdef _NO_EXCEPTIONS + #ifdef Z7_NO_EXCEPTIONS ErrorCode = S_OK; #endif NumExtraBytes = 0; } void Init() throw(); - + + Z7_FORCE_INLINE bool ReadByte(Byte &b) { if (_buf >= _bufLim) @@ -67,7 +76,17 @@ public: b = *_buf++; return true; } + + Z7_FORCE_INLINE + bool ReadByte_FromBuf(Byte &b) + { + if (_buf >= _bufLim) + return false; + b = *_buf++; + return true; + } + Z7_FORCE_INLINE Byte ReadByte() { if (_buf >= _bufLim) diff --git a/3rdparty/lzma/CPP/7zip/Common/InOutTempBuffer.cpp b/3rdparty/lzma/CPP/7zip/Common/InOutTempBuffer.cpp index 85d6a1aa921..3f7272ef820 100644 --- a/3rdparty/lzma/CPP/7zip/Common/InOutTempBuffer.cpp +++ b/3rdparty/lzma/CPP/7zip/Common/InOutTempBuffer.cpp @@ -2,126 +2,236 @@ #include "StdAfx.h" -#include "../../../C/7zCrc.h" - -#include "../../Common/Defs.h" +#include "../../../C/Alloc.h" #include "InOutTempBuffer.h" + #include "StreamUtils.h" -using namespace NWindows; -using namespace NFile; -using namespace NDir; +#ifdef USE_InOutTempBuffer_FILE + +#include "../../../C/7zCrc.h" + +#define kTempFilePrefixString FTEXT("7zt") +/* + Total buffer size limit, if we use temp file scheme: + 32-bit: 16 MiB = 1 MiB * 16 buffers + 64-bit: 4 GiB = 1 MiB * 4096 buffers +*/ +static const size_t kNumBufsMax = (size_t)1 << (sizeof(size_t) * 2 - 4); -static const size_t kTempBufSize = (1 << 20); +#endif -static CFSTR kTempFilePrefixString = FTEXT("7zt"); +static const size_t kBufSize = (size_t)1 << 20; -CInOutTempBuffer::CInOutTempBuffer(): _buf(NULL) { } -void CInOutTempBuffer::Create() +CInOutTempBuffer::CInOutTempBuffer(): + _size(0), + _bufs(NULL), + _numBufs(0), + _numFilled(0) { - if (!_buf) - _buf = new Byte[kTempBufSize]; + #ifdef USE_InOutTempBuffer_FILE + _tempFile_Created = false; + _useMemOnly = false; + _crc = CRC_INIT_VAL; + #endif } CInOutTempBuffer::~CInOutTempBuffer() { - delete []_buf; + for (size_t i = 0; i < _numBufs; i++) + MyFree(_bufs[i]); + MyFree(_bufs); } -void CInOutTempBuffer::InitWriting() -{ - _bufPos = 0; - _tempFileCreated = false; - _size = 0; - _crc = CRC_INIT_VAL; -} -bool CInOutTempBuffer::WriteToFile(const void *data, UInt32 size) +void *CInOutTempBuffer::GetBuf(size_t index) { - if (size == 0) - return true; - if (!_tempFileCreated) + if (index >= _numBufs) + { + const size_t num = (_numBufs == 0 ? 16 : _numBufs * 2); + void **p = (void **)MyRealloc(_bufs, num * sizeof(void *)); + if (!p) + return NULL; + _bufs = p; + memset(p + _numBufs, 0, (num - _numBufs) * sizeof(void *)); + _numBufs = num; + } + + void *buf = _bufs[index]; + if (!buf) { - if (!_tempFile.CreateRandomInTempFolder(kTempFilePrefixString, &_outFile)) - return false; - _tempFileCreated = true; + buf = MyAlloc(kBufSize); + if (buf) + _bufs[index] = buf; } - UInt32 processed; - if (!_outFile.Write(data, size, processed)) - return false; - _crc = CrcUpdate(_crc, data, processed); - _size += processed; - return (processed == size); + return buf; } -bool CInOutTempBuffer::Write(const void *data, UInt32 size) + +HRESULT CInOutTempBuffer::Write_HRESULT(const void *data, UInt32 size) { if (size == 0) - return true; - size_t cur = kTempBufSize - _bufPos; - if (cur != 0) + return S_OK; + + #ifdef USE_InOutTempBuffer_FILE + if (!_tempFile_Created) + #endif + for (;;) // loop for additional attemp to allocate memory after file creation error { - if (cur > size) - cur = size; - memcpy(_buf + _bufPos, data, cur); - _crc = CrcUpdate(_crc, data, cur); - _bufPos += cur; - _size += cur; - size -= (UInt32)cur; - data = ((const Byte *)data) + cur; + #ifdef USE_InOutTempBuffer_FILE + bool allocError = false; + #endif + + for (;;) // loop for writing to buffers + { + const size_t index = (size_t)(_size / kBufSize); + + #ifdef USE_InOutTempBuffer_FILE + if (index >= kNumBufsMax && !_useMemOnly) + break; + #endif + + void *buf = GetBuf(index); + if (!buf) + { + #ifdef USE_InOutTempBuffer_FILE + if (!_useMemOnly) + { + allocError = true; + break; + } + #endif + return E_OUTOFMEMORY; + } + + const size_t offset = (size_t)(_size) & (kBufSize - 1); + size_t cur = kBufSize - offset; + if (cur > size) + cur = size; + memcpy((Byte *)buf + offset, data, cur); + _size += cur; + if (index >= _numFilled) + _numFilled = index + 1; + data = (const void *)((const Byte *)data + cur); + size -= (UInt32)cur; + if (size == 0) + return S_OK; + } + + #ifdef USE_InOutTempBuffer_FILE + #ifndef _WIN32 + _outFile.mode_for_Create = 0600; // only owner will have the rights to access this file + #endif + if (_tempFile.CreateRandomInTempFolder(kTempFilePrefixString, &_outFile)) + { + _tempFile_Created = true; + break; + } + _useMemOnly = true; + if (allocError) + return GetLastError_noZero_HRESULT(); + #endif } - return WriteToFile(data, size); + + #ifdef USE_InOutTempBuffer_FILE + if (!_outFile.WriteFull(data, size)) + return GetLastError_noZero_HRESULT(); + _crc = CrcUpdate(_crc, data, size); + _size += size; + return S_OK; + #endif } + HRESULT CInOutTempBuffer::WriteToStream(ISequentialOutStream *stream) { - if (!_outFile.Close()) - return E_FAIL; + UInt64 rem = _size; + // if (rem == 0) return S_OK; - UInt64 size = 0; - UInt32 crc = CRC_INIT_VAL; + const size_t numFilled = _numFilled; + _numFilled = 0; - if (_bufPos != 0) + for (size_t i = 0; i < numFilled; i++) { - RINOK(WriteStream(stream, _buf, _bufPos)); - crc = CrcUpdate(crc, _buf, _bufPos); - size += _bufPos; - } - - if (_tempFileCreated) - { - NIO::CInFile inFile; - if (!inFile.Open(_tempFile.GetPath())) + if (rem == 0) return E_FAIL; - while (size < _size) + size_t cur = kBufSize; + if (cur > rem) + cur = (size_t)rem; + RINOK(WriteStream(stream, _bufs[i], cur)) + rem -= cur; + #ifdef USE_InOutTempBuffer_FILE + // we will use _bufs[0] later for writing from temp file + if (i != 0 || !_tempFile_Created) + #endif { - UInt32 processed; - if (!inFile.ReadPart(_buf, kTempBufSize, processed)) - return E_FAIL; - if (processed == 0) - break; - RINOK(WriteStream(stream, _buf, processed)); - crc = CrcUpdate(crc, _buf, processed); - size += processed; + MyFree(_bufs[i]); + _bufs[i] = NULL; } } - - return (_crc == crc && size == _size) ? S_OK : E_FAIL; -} -/* -STDMETHODIMP CSequentialOutTempBufferImp::Write(const void *data, UInt32 size, UInt32 *processed) -{ - if (!_buf->Write(data, size)) - { - if (processed) - *processed = 0; + + #ifdef USE_InOutTempBuffer_FILE + + if (rem == 0) + return _tempFile_Created ? E_FAIL : S_OK; + + if (!_tempFile_Created) return E_FAIL; + + if (!_outFile.Close()) + return GetLastError_noZero_HRESULT(); + + HRESULT hres; + void *buf = GetBuf(0); // index + if (!buf) + hres = E_OUTOFMEMORY; + else + { + NWindows::NFile::NIO::CInFile inFile; + if (!inFile.Open(_tempFile.GetPath())) + hres = GetLastError_noZero_HRESULT(); + else + { + UInt32 crc = CRC_INIT_VAL; + for (;;) + { + size_t processed; + if (!inFile.ReadFull(buf, kBufSize, processed)) + { + hres = GetLastError_noZero_HRESULT(); + break; + } + if (processed == 0) + { + // we compare crc without CRC_GET_DIGEST + hres = (_crc == crc ? S_OK : E_FAIL); + break; + } + size_t n = processed; + if (n > rem) + n = (size_t)rem; + hres = WriteStream(stream, buf, n); + if (hres != S_OK) + break; + crc = CrcUpdate(crc, buf, n); + rem -= n; + if (n != processed) + { + hres = E_FAIL; + break; + } + } + } } - if (processed) - *processed = size; - return S_OK; + + // _tempFile.DisableDeleting(); // for debug + _tempFile.Remove(); + RINOK(hres) + + #endif + + return rem == 0 ? S_OK : E_FAIL; } -*/ diff --git a/3rdparty/lzma/CPP/7zip/Common/InOutTempBuffer.h b/3rdparty/lzma/CPP/7zip/Common/InOutTempBuffer.h index 204a105f1de..345c3863c40 100644 --- a/3rdparty/lzma/CPP/7zip/Common/InOutTempBuffer.h +++ b/3rdparty/lzma/CPP/7zip/Common/InOutTempBuffer.h @@ -1,48 +1,45 @@ // InOutTempBuffer.h -#ifndef __IN_OUT_TEMP_BUFFER_H -#define __IN_OUT_TEMP_BUFFER_H +#ifndef ZIP7_INC_IN_OUT_TEMP_BUFFER_H +#define ZIP7_INC_IN_OUT_TEMP_BUFFER_H -#include "../../Common/MyCom.h" +// #ifdef _WIN32 +#define USE_InOutTempBuffer_FILE +// #endif + +#ifdef USE_InOutTempBuffer_FILE #include "../../Windows/FileDir.h" +#endif #include "../IStream.h" class CInOutTempBuffer { - NWindows::NFile::NDir::CTempFile _tempFile; - NWindows::NFile::NIO::COutFile _outFile; - Byte *_buf; - size_t _bufPos; UInt64 _size; + void **_bufs; + size_t _numBufs; + size_t _numFilled; + + #ifdef USE_InOutTempBuffer_FILE + + bool _tempFile_Created; + bool _useMemOnly; UInt32 _crc; - bool _tempFileCreated; + // COutFile object must be declared after CTempFile object for correct destructor order + NWindows::NFile::NDir::CTempFile _tempFile; + NWindows::NFile::NIO::COutFile _outFile; + + #endif + + void *GetBuf(size_t index); - bool WriteToFile(const void *data, UInt32 size); + Z7_CLASS_NO_COPY(CInOutTempBuffer) public: CInOutTempBuffer(); ~CInOutTempBuffer(); - void Create(); - - void InitWriting(); - bool Write(const void *data, UInt32 size); - + HRESULT Write_HRESULT(const void *data, UInt32 size); HRESULT WriteToStream(ISequentialOutStream *stream); UInt64 GetDataSize() const { return _size; } }; -/* -class CSequentialOutTempBufferImp: - public ISequentialOutStream, - public CMyUnknownImp -{ - CInOutTempBuffer *_buf; -public: - void Init(CInOutTempBuffer *buffer) { _buf = buffer; } - MY_UNKNOWN_IMP - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); -}; -*/ - #endif diff --git a/3rdparty/lzma/CPP/7zip/Common/LimitedStreams.cpp b/3rdparty/lzma/CPP/7zip/Common/LimitedStreams.cpp index 8e032561662..664cd0c4b5c 100644 --- a/3rdparty/lzma/CPP/7zip/Common/LimitedStreams.cpp +++ b/3rdparty/lzma/CPP/7zip/Common/LimitedStreams.cpp @@ -6,7 +6,7 @@ #include "LimitedStreams.h" -STDMETHODIMP CLimitedSequentialInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CLimitedSequentialInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { UInt32 realProcessedSize = 0; { @@ -27,7 +27,7 @@ STDMETHODIMP CLimitedSequentialInStream::Read(void *data, UInt32 size, UInt32 *p return result; } -STDMETHODIMP CLimitedInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CLimitedInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -46,7 +46,7 @@ STDMETHODIMP CLimitedInStream::Read(void *data, UInt32 size, UInt32 *processedSi if (newPos != _physPos) { _physPos = newPos; - RINOK(SeekToPhys()); + RINOK(SeekToPhys()) } HRESULT res = _stream->Read(data, size, &size); if (processedSize) @@ -56,7 +56,7 @@ STDMETHODIMP CLimitedInStream::Read(void *data, UInt32 size, UInt32 *processedSi return res; } -STDMETHODIMP CLimitedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(CLimitedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { switch (seekOrigin) { @@ -67,7 +67,7 @@ STDMETHODIMP CLimitedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *new } if (offset < 0) return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - _virtPos = offset; + _virtPos = (UInt64)offset; if (newPosition) *newPosition = _virtPos; return S_OK; @@ -75,17 +75,17 @@ STDMETHODIMP CLimitedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *new HRESULT CreateLimitedInStream(IInStream *inStream, UInt64 pos, UInt64 size, ISequentialInStream **resStream) { - *resStream = 0; + *resStream = NULL; CLimitedInStream *streamSpec = new CLimitedInStream; CMyComPtr<ISequentialInStream> streamTemp = streamSpec; streamSpec->SetStream(inStream); - RINOK(streamSpec->InitAndSeek(pos, size)); + RINOK(streamSpec->InitAndSeek(pos, size)) streamSpec->SeekToStart(); *resStream = streamTemp.Detach(); return S_OK; } -STDMETHODIMP CClusterInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CClusterInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -110,12 +110,12 @@ STDMETHODIMP CClusterInStream::Read(void *data, UInt32 size, UInt32 *processedSi if (newPos != _physPos) { _physPos = newPos; - RINOK(SeekToPhys()); + RINOK(SeekToPhys()) } _curRem = blockSize - offsetInBlock; - for (int i = 1; i < 64 && (virtBlock + i) < (UInt32)Vector.Size() && phyBlock + i == Vector[virtBlock + i]; i++) + for (unsigned i = 1; i < 64 && (virtBlock + i) < (UInt32)Vector.Size() && phyBlock + i == Vector[virtBlock + i]; i++) _curRem += (UInt32)1 << BlockSizeLog; } @@ -130,7 +130,7 @@ STDMETHODIMP CClusterInStream::Read(void *data, UInt32 size, UInt32 *processedSi return res; } -STDMETHODIMP CClusterInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(CClusterInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { switch (seekOrigin) { @@ -143,56 +143,82 @@ STDMETHODIMP CClusterInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *new return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; if (_virtPos != (UInt64)offset) _curRem = 0; - _virtPos = offset; + _virtPos = (UInt64)offset; if (newPosition) - *newPosition = offset; + *newPosition = (UInt64)offset; return S_OK; } -STDMETHODIMP CExtentsStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CExtentsStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; - if (_virtPos >= Extents.Back().Virt) + const UInt64 virt = _virtPos; + if (virt >= Extents.Back().Virt) return S_OK; if (size == 0) return S_OK; - unsigned left = 0, right = Extents.Size() - 1; - for (;;) + unsigned left = _prevExtentIndex; + if (virt < Extents[left].Virt || + virt >= Extents[left + 1].Virt) { - unsigned mid = (left + right) / 2; - if (mid == left) - break; - if (_virtPos < Extents[mid].Virt) - right = mid; - else - left = mid; + left = 0; + unsigned right = Extents.Size() - 1; + for (;;) + { + const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); + if (mid == left) + break; + if (virt < Extents[mid].Virt) + right = mid; + else + left = mid; + } + _prevExtentIndex = left; } - const CSeekExtent &extent = Extents[left]; - UInt64 phyPos = extent.Phy + (_virtPos - extent.Virt); - if (_needStartSeek || _phyPos != phyPos) { - _needStartSeek = false; - _phyPos = phyPos; - RINOK(SeekToPhys()); + const UInt64 rem = Extents[left + 1].Virt - virt; + if (size > rem) + size = (UInt32)rem; } - UInt64 rem = Extents[left + 1].Virt - _virtPos; - if (size > rem) - size = (UInt32)rem; + const CSeekExtent &extent = Extents[left]; - HRESULT res = Stream->Read(data, size, &size); - _phyPos += size; + if (extent.Is_ZeroFill()) + { + memset(data, 0, size); + _virtPos += size; + if (processedSize) + *processedSize = size; + return S_OK; + } + + { + const UInt64 phy = extent.Phy + (virt - extent.Virt); + if (_phyPos != phy) + { + _phyPos = (UInt64)0 - 1; // we don't trust seek_pos in case of error + RINOK(InStream_SeekSet(Stream, phy)) + _phyPos = phy; + } + } + + const HRESULT res = Stream->Read(data, size, &size); _virtPos += size; + if (res == S_OK) + _phyPos += size; + else + _phyPos = (UInt64)0 - 1; // we don't trust seek_pos in case of error if (processedSize) *processedSize = size; return res; } -STDMETHODIMP CExtentsStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) + +Z7_COM7F_IMF(CExtentsStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { switch (seekOrigin) { @@ -203,14 +229,14 @@ STDMETHODIMP CExtentsStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPo } if (offset < 0) return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - _virtPos = offset; + _virtPos = (UInt64)offset; if (newPosition) *newPosition = _virtPos; return S_OK; } -STDMETHODIMP CLimitedSequentialOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CLimitedSequentialOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { HRESULT result = S_OK; if (processedSize) @@ -237,7 +263,7 @@ STDMETHODIMP CLimitedSequentialOutStream::Write(const void *data, UInt32 size, U } -STDMETHODIMP CTailInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CTailInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { UInt32 cur; HRESULT res = Stream->Read(data, size, &cur); @@ -247,7 +273,7 @@ STDMETHODIMP CTailInStream::Read(void *data, UInt32 size, UInt32 *processedSize) return res; } -STDMETHODIMP CTailInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(CTailInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { switch (seekOrigin) { @@ -256,7 +282,7 @@ STDMETHODIMP CTailInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPos case STREAM_SEEK_END: { UInt64 pos = 0; - RINOK(Stream->Seek(offset, STREAM_SEEK_END, &pos)); + RINOK(Stream->Seek(offset, STREAM_SEEK_END, &pos)) if (pos < Offset) return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; _virtPos = pos - Offset; @@ -268,13 +294,13 @@ STDMETHODIMP CTailInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPos } if (offset < 0) return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - _virtPos = offset; + _virtPos = (UInt64)offset; if (newPosition) *newPosition = _virtPos; - return Stream->Seek(Offset + _virtPos, STREAM_SEEK_SET, NULL); + return InStream_SeekSet(Stream, Offset + _virtPos); } -STDMETHODIMP CLimitedCachedInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CLimitedCachedInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -303,7 +329,7 @@ STDMETHODIMP CLimitedCachedInStream::Read(void *data, UInt32 size, UInt32 *proce if (newPos != _physPos) { _physPos = newPos; - RINOK(SeekToPhys()); + RINOK(SeekToPhys()) } res = _stream->Read(data, size, &size); _physPos += size; @@ -314,7 +340,7 @@ STDMETHODIMP CLimitedCachedInStream::Read(void *data, UInt32 size, UInt32 *proce return res; } -STDMETHODIMP CLimitedCachedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(CLimitedCachedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { switch (seekOrigin) { @@ -325,13 +351,13 @@ STDMETHODIMP CLimitedCachedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt6 } if (offset < 0) return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - _virtPos = offset; + _virtPos = (UInt64)offset; if (newPosition) *newPosition = _virtPos; return S_OK; } -STDMETHODIMP CTailOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CTailOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { UInt32 cur; HRESULT res = Stream->Write(data, size, &cur); @@ -343,7 +369,7 @@ STDMETHODIMP CTailOutStream::Write(const void *data, UInt32 size, UInt32 *proces return res; } -STDMETHODIMP CTailOutStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(CTailOutStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { switch (seekOrigin) { @@ -354,13 +380,13 @@ STDMETHODIMP CTailOutStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPo } if (offset < 0) return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - _virtPos = offset; + _virtPos = (UInt64)offset; if (newPosition) *newPosition = _virtPos; - return Stream->Seek(Offset + _virtPos, STREAM_SEEK_SET, NULL); + return Stream->Seek((Int64)(Offset + _virtPos), STREAM_SEEK_SET, NULL); } -STDMETHODIMP CTailOutStream::SetSize(UInt64 newSize) +Z7_COM7F_IMF(CTailOutStream::SetSize(UInt64 newSize)) { _virtSize = newSize; return Stream->SetSize(Offset + newSize); diff --git a/3rdparty/lzma/CPP/7zip/Common/LimitedStreams.h b/3rdparty/lzma/CPP/7zip/Common/LimitedStreams.h index fb1ac3cd6bd..69fcdcdb0e5 100644 --- a/3rdparty/lzma/CPP/7zip/Common/LimitedStreams.h +++ b/3rdparty/lzma/CPP/7zip/Common/LimitedStreams.h @@ -1,17 +1,19 @@ // LimitedStreams.h -#ifndef __LIMITED_STREAMS_H -#define __LIMITED_STREAMS_H +#ifndef ZIP7_INC_LIMITED_STREAMS_H +#define ZIP7_INC_LIMITED_STREAMS_H #include "../../Common/MyBuffer.h" #include "../../Common/MyCom.h" #include "../../Common/MyVector.h" #include "../IStream.h" -class CLimitedSequentialInStream: - public ISequentialInStream, - public CMyUnknownImp -{ +#include "StreamUtils.h" + +Z7_CLASS_IMP_COM_1( + CLimitedSequentialInStream + , ISequentialInStream +) CMyComPtr<ISequentialInStream> _stream; UInt64 _size; UInt64 _pos; @@ -25,26 +27,22 @@ public: _pos = 0; _wasFinished = false; } - - MY_UNKNOWN_IMP1(ISequentialInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); UInt64 GetSize() const { return _pos; } UInt64 GetRem() const { return _size - _pos; } bool WasFinished() const { return _wasFinished; } }; -class CLimitedInStream: - public IInStream, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_IInStream( + CLimitedInStream +) CMyComPtr<IInStream> _stream; UInt64 _virtPos; UInt64 _physPos; UInt64 _size; UInt64 _startOffset; - HRESULT SeekToPhys() { return _stream->Seek(_physPos, STREAM_SEEK_SET, NULL); } + HRESULT SeekToPhys() { return InStream_SeekSet(_stream, _physPos); } public: void SetStream(IInStream *stream) { _stream = stream; } HRESULT InitAndSeek(UInt64 startOffset, UInt64 size) @@ -55,21 +53,15 @@ public: _size = size; return SeekToPhys(); } - - MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - HRESULT SeekToStart() { return Seek(0, STREAM_SEEK_SET, NULL); } }; HRESULT CreateLimitedInStream(IInStream *inStream, UInt64 pos, UInt64 size, ISequentialInStream **resStream); -class CClusterInStream: - public IInStream, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_IInStream( + CClusterInStream +) UInt64 _virtPos; UInt64 _physPos; UInt32 _curRem; @@ -80,7 +72,7 @@ public: CRecordVector<UInt32> Vector; UInt64 StartOffset; - HRESULT SeekToPhys() { return Stream->Seek(_physPos, STREAM_SEEK_SET, NULL); } + HRESULT SeekToPhys() { return InStream_SeekSet(Stream, _physPos); } HRESULT InitAndSeek() { @@ -94,57 +86,52 @@ public: } return S_OK; } +}; - MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); -}; + +const UInt64 k_SeekExtent_Phy_Type_ZeroFill = (UInt64)(Int64)-1; struct CSeekExtent { - UInt64 Phy; UInt64 Virt; -}; + UInt64 Phy; -class CExtentsStream: - public IInStream, - public CMyUnknownImp -{ - UInt64 _phyPos; - UInt64 _virtPos; - bool _needStartSeek; + void SetAs_ZeroFill() { Phy = k_SeekExtent_Phy_Type_ZeroFill; } + bool Is_ZeroFill() const { return Phy == k_SeekExtent_Phy_Type_ZeroFill; } +}; - HRESULT SeekToPhys() { return Stream->Seek(_phyPos, STREAM_SEEK_SET, NULL); } +Z7_CLASS_IMP_IInStream( + CExtentsStream +) + UInt64 _virtPos; + UInt64 _phyPos; + unsigned _prevExtentIndex; public: CMyComPtr<IInStream> Stream; CRecordVector<CSeekExtent> Extents; - MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); void ReleaseStream() { Stream.Release(); } - void Init() { _virtPos = 0; - _phyPos = 0; - _needStartSeek = true; + _phyPos = (UInt64)0 - 1; // we need Seek() for Stream + _prevExtentIndex = 0; } }; -class CLimitedSequentialOutStream: - public ISequentialOutStream, - public CMyUnknownImp -{ + + +Z7_CLASS_IMP_COM_1( + CLimitedSequentialOutStream + , ISequentialOutStream +) CMyComPtr<ISequentialOutStream> _stream; UInt64 _size; bool _overflow; bool _overflowIsAllowed; public: - MY_UNKNOWN_IMP1(ISequentialOutStream) - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); void SetStream(ISequentialOutStream *stream) { _stream = stream; } void ReleaseStream() { _stream.Release(); } void Init(UInt64 size, bool overflowIsAllowed = false) @@ -158,10 +145,9 @@ public: }; -class CTailInStream: - public IInStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_IInStream( + CTailInStream +) UInt64 _virtPos; public: CMyComPtr<IInStream> Stream; @@ -171,19 +157,13 @@ public: { _virtPos = 0; } - - MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - - HRESULT SeekToStart() { return Stream->Seek(Offset, STREAM_SEEK_SET, NULL); } + HRESULT SeekToStart() { return InStream_SeekSet(Stream, Offset); } }; -class CLimitedCachedInStream: - public IInStream, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_IInStream( + CLimitedCachedInStream +) CMyComPtr<IInStream> _stream; UInt64 _virtPos; UInt64 _physPos; @@ -194,8 +174,7 @@ class CLimitedCachedInStream: size_t _cacheSize; size_t _cachePhyPos; - - HRESULT SeekToPhys() { return _stream->Seek(_physPos, STREAM_SEEK_SET, NULL); } + HRESULT SeekToPhys() { return InStream_SeekSet(_stream, _physPos); } public: CByteBuffer Buffer; @@ -216,37 +195,27 @@ public: return SeekToPhys(); } - MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - HRESULT SeekToStart() { return Seek(0, STREAM_SEEK_SET, NULL); } }; -class CTailOutStream: + +class CTailOutStream Z7_final : public IOutStream, public CMyUnknownImp { + Z7_IFACES_IMP_UNK_2(ISequentialOutStream, IOutStream) + UInt64 _virtPos; UInt64 _virtSize; public: CMyComPtr<IOutStream> Stream; UInt64 Offset; - virtual ~CTailOutStream() {} - - MY_UNKNOWN_IMP2(ISequentialOutStream, IOutStream) - void Init() { _virtPos = 0; _virtSize = 0; } - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - STDMETHOD(SetSize)(UInt64 newSize); }; #endif diff --git a/3rdparty/lzma/CPP/7zip/Common/LockedStream.h b/3rdparty/lzma/CPP/7zip/Common/LockedStream.h index efebf197553..99ee8055c6e 100644 --- a/3rdparty/lzma/CPP/7zip/Common/LockedStream.h +++ b/3rdparty/lzma/CPP/7zip/Common/LockedStream.h @@ -1,6 +1,6 @@ // LockedStream.h -#ifndef __LOCKED_STREAM_H -#define __LOCKED_STREAM_H +#ifndef ZIP7_INC_LOCKED_STREAM_H +#define ZIP7_INC_LOCKED_STREAM_H #endif diff --git a/3rdparty/lzma/CPP/7zip/Common/MethodId.h b/3rdparty/lzma/CPP/7zip/Common/MethodId.h index 28b615fcd3e..19b1f10d5fa 100644 --- a/3rdparty/lzma/CPP/7zip/Common/MethodId.h +++ b/3rdparty/lzma/CPP/7zip/Common/MethodId.h @@ -1,7 +1,7 @@ // MethodId.h -#ifndef __7Z_METHOD_ID_H -#define __7Z_METHOD_ID_H +#ifndef ZIP7_INC_7Z_METHOD_ID_H +#define ZIP7_INC_7Z_METHOD_ID_H #include "../../Common/MyTypes.h" diff --git a/3rdparty/lzma/CPP/7zip/Common/MethodProps.cpp b/3rdparty/lzma/CPP/7zip/Common/MethodProps.cpp index 09f7b29cc24..fe60f610064 100644 --- a/3rdparty/lzma/CPP/7zip/Common/MethodProps.cpp +++ b/3rdparty/lzma/CPP/7zip/Common/MethodProps.cpp @@ -8,9 +8,39 @@ using namespace NWindows; -bool StringToBool(const UString &s, bool &res) +UInt64 Calc_From_Val_Percents(UInt64 val, UInt64 percents) { - if (s.IsEmpty() || (s[0] == '+' && s[1] == 0) || StringsAreEqualNoCase_Ascii(s, "ON")) + // if (percents == 0) return 0; + const UInt64 q = percents / 100; + const UInt32 r = (UInt32)(percents % 100); + UInt64 res = 0; + + if (q != 0) + { + if (val > (UInt64)(Int64)-1 / q) + return (UInt64)(Int64)-1; + res = val * q; + } + + if (r != 0) + { + UInt64 v2; + if (val <= (UInt64)(Int64)-1 / r) + v2 = val * r / 100; + else + v2 = val / 100 * r; + res += v2; + if (res < v2) + return (UInt64)(Int64)-1; + } + + return res; +} + + +bool StringToBool(const wchar_t *s, bool &res) +{ + if (s[0] == 0 || (s[0] == '+' && s[1] == 0) || StringsAreEqualNoCase_Ascii(s, "ON")) { res = true; return true; @@ -42,10 +72,18 @@ unsigned ParseStringToUInt32(const UString &srcString, UInt32 &number) return (unsigned)(end - start); } +static unsigned ParseStringToUInt64(const UString &srcString, UInt64 &number) +{ + const wchar_t *start = srcString; + const wchar_t *end; + number = ConvertStringToUInt64(start, &end); + return (unsigned)(end - start); +} + HRESULT ParsePropToUInt32(const UString &name, const PROPVARIANT &prop, UInt32 &resValue) { // =VT_UI4 - // =VT_EMPTY + // =VT_EMPTY : it doesn't change (resValue), and returns S_OK // {stringUInt32}=VT_EMPTY if (prop.vt == VT_UI4) @@ -66,66 +104,151 @@ HRESULT ParsePropToUInt32(const UString &name, const PROPVARIANT &prop, UInt32 & return S_OK; } -HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads) + + +HRESULT ParseMtProp2(const UString &name, const PROPVARIANT &prop, UInt32 &numThreads, bool &force) { + force = false; + UString s; if (name.IsEmpty()) { - switch (prop.vt) + if (prop.vt == VT_UI4) + { + numThreads = prop.ulVal; + force = true; + return S_OK; + } + bool val; + HRESULT res = PROPVARIANT_to_bool(prop, val); + if (res == S_OK) { - case VT_UI4: - numThreads = prop.ulVal; - break; - default: + if (!val) { - bool val; - RINOK(PROPVARIANT_to_bool(prop, val)); - numThreads = (val ? defaultNumThreads : 1); - break; + numThreads = 1; + force = true; } + // force = true; for debug + // "(VT_BOOL = VARIANT_TRUE)" set "force = false" and doesn't change numThreads + return S_OK; } - return S_OK; + if (prop.vt != VT_BSTR) + return res; + s.SetFromBstr(prop.bstrVal); + if (s.IsEmpty()) + return E_INVALIDARG; } - if (prop.vt != VT_EMPTY) + else + { + if (prop.vt != VT_EMPTY) + return E_INVALIDARG; + s = name; + } + + s.MakeLower_Ascii(); + const wchar_t *start = s; + UInt32 v = numThreads; + + /* we force up, if threads number specified + only `d` will force it down */ + bool force_loc = true; + for (;;) + { + const wchar_t c = *start; + if (!c) + break; + if (c == 'd') + { + force_loc = false; // force down + start++; + continue; + } + if (c == 'u') + { + force_loc = true; // force up + start++; + continue; + } + bool isPercent = false; + if (c == 'p') + { + isPercent = true; + start++; + } + const wchar_t *end; + v = ConvertStringToUInt32(start, &end); + if (end == start) + return E_INVALIDARG; + if (isPercent) + v = numThreads * v / 100; + start = end; + } + + numThreads = v; + force = force_loc; + return S_OK; +} + + + +static HRESULT SetLogSizeProp(UInt64 number, NCOM::CPropVariant &destProp) +{ + if (number >= 64) return E_INVALIDARG; - return ParsePropToUInt32(name, prop, numThreads); + UInt32 val32; + if (number < 32) + val32 = (UInt32)1 << (unsigned)number; + /* + else if (number == 32 && reduce_4GB_to_32bits) + val32 = (UInt32)(Int32)-1; + */ + else + { + destProp = (UInt64)((UInt64)1 << (unsigned)number); + return S_OK; + } + destProp = (UInt32)val32; + return S_OK; } static HRESULT StringToDictSize(const UString &s, NCOM::CPropVariant &destProp) { + /* if (reduce_4GB_to_32bits) we can reduce (4 GiB) property to (4 GiB - 1). + to fit the value to UInt32 for clients that do not support 64-bit values */ + const wchar_t *end; - UInt32 number = ConvertStringToUInt32(s, &end); - unsigned numDigits = (unsigned)(end - s); + const UInt64 number = ConvertStringToUInt64(s, &end); + const unsigned numDigits = (unsigned)(end - s.Ptr()); if (numDigits == 0 || s.Len() > numDigits + 1) return E_INVALIDARG; if (s.Len() == numDigits) - { - if (number >= 64) - return E_INVALIDARG; - if (number < 32) - destProp = (UInt32)((UInt32)1 << (unsigned)number); - else - destProp = (UInt64)((UInt64)1 << (unsigned)number); - return S_OK; - } + return SetLogSizeProp(number, destProp); unsigned numBits; switch (MyCharLower_Ascii(s[numDigits])) { - case 'b': destProp = number; return S_OK; + case 'b': numBits = 0; break; case 'k': numBits = 10; break; case 'm': numBits = 20; break; case 'g': numBits = 30; break; default: return E_INVALIDARG; } - if (number < ((UInt32)1 << (32 - numBits))) - destProp = (UInt32)(number << numBits); + const UInt64 range4g = ((UInt64)1 << (32 - numBits)); + if (number < range4g) + destProp = (UInt32)((UInt32)number << numBits); + /* + else if (number == range4g && reduce_4GB_to_32bits) + destProp = (UInt32)(Int32)-1; + */ + else if (numBits == 0) + destProp = (UInt64)number; + else if (number >= ((UInt64)1 << (64 - numBits))) + return E_INVALIDARG; else destProp = (UInt64)((UInt64)number << numBits); - return S_OK; } @@ -133,28 +256,32 @@ static HRESULT StringToDictSize(const UString &s, NCOM::CPropVariant &destProp) static HRESULT PROPVARIANT_to_DictSize(const PROPVARIANT &prop, NCOM::CPropVariant &destProp) { if (prop.vt == VT_UI4) + return SetLogSizeProp(prop.ulVal, destProp); + + if (prop.vt == VT_BSTR) { - UInt32 v = prop.ulVal; - if (v >= 64) - return E_INVALIDARG; - if (v < 32) - destProp = (UInt32)((UInt32)1 << (unsigned)v); - else - destProp = (UInt64)((UInt64)1 << (unsigned)v); - return S_OK; + UString s; + s = prop.bstrVal; + return StringToDictSize(s, destProp); } - if (prop.vt == VT_BSTR) - return StringToDictSize(prop.bstrVal, destProp); return E_INVALIDARG; } -void CProps::AddProp32(PROPID propid, UInt32 level) +void CProps::AddProp32(PROPID propid, UInt32 val) +{ + CProp &prop = Props.AddNew(); + prop.IsOptional = true; + prop.Id = propid; + prop.Value = (UInt32)val; +} + +void CProps::AddPropBool(PROPID propid, bool val) { CProp &prop = Props.AddNew(); prop.IsOptional = true; prop.Id = propid; - prop.Value = (UInt32)level; + prop.Value = val; } class CCoderProps @@ -164,10 +291,12 @@ class CCoderProps unsigned _numProps; unsigned _numPropsMax; public: - CCoderProps(unsigned numPropsMax) + CCoderProps(unsigned numPropsMax): + _propIDs(NULL), + _props(NULL), + _numProps(0), + _numPropsMax(numPropsMax) { - _numPropsMax = numPropsMax; - _numProps = 0; _propIDs = new PROPID[numPropsMax]; _props = new NCOM::CPropVariant[numPropsMax]; } @@ -194,7 +323,15 @@ void CCoderProps::AddProp(const CProp &prop) HRESULT CProps::SetCoderProps(ICompressSetCoderProperties *scp, const UInt64 *dataSizeReduce) const { - CCoderProps coderProps(Props.Size() + (dataSizeReduce ? 1 : 0)); + return SetCoderProps_DSReduce_Aff(scp, dataSizeReduce, NULL); +} + +HRESULT CProps::SetCoderProps_DSReduce_Aff( + ICompressSetCoderProperties *scp, + const UInt64 *dataSizeReduce, + const UInt64 *affinity) const +{ + CCoderProps coderProps(Props.Size() + (dataSizeReduce ? 1 : 0) + (affinity ? 1 : 0) ); FOR_VECTOR (i, Props) coderProps.AddProp(Props[i]); if (dataSizeReduce) @@ -204,27 +341,34 @@ HRESULT CProps::SetCoderProps(ICompressSetCoderProperties *scp, const UInt64 *da prop.Value = *dataSizeReduce; coderProps.AddProp(prop); } + if (affinity) + { + CProp prop; + prop.Id = NCoderPropID::kAffinity; + prop.Value = *affinity; + coderProps.AddProp(prop); + } return coderProps.SetProps(scp); } int CMethodProps::FindProp(PROPID id) const { - for (int i = Props.Size() - 1; i >= 0; i--) - if (Props[i].Id == id) - return i; + for (unsigned i = Props.Size(); i != 0;) + if (Props[--i].Id == id) + return (int)i; return -1; } -int CMethodProps::GetLevel() const +unsigned CMethodProps::GetLevel() const { int i = FindProp(NCoderPropID::kLevel); if (i < 0) return 5; - if (Props[i].Value.vt != VT_UI4) + if (Props[(unsigned)i].Value.vt != VT_UI4) return 9; - UInt32 level = Props[i].Value.ulVal; - return level > 9 ? 9 : (int)level; + UInt32 level = Props[(unsigned)i].Value.ulVal; + return level > 9 ? 9 : (unsigned)level; } struct CNameToPropID @@ -233,13 +377,16 @@ struct CNameToPropID const char *Name; }; + +// the following are related to NCoderPropID::EEnum values +// NCoderPropID::k_NUM_DEFINED static const CNameToPropID g_NameToPropID[] = { { VT_UI4, "" }, { VT_UI4, "d" }, { VT_UI4, "mem" }, { VT_UI4, "o" }, - { VT_UI4, "c" }, + { VT_UI8, "c" }, { VT_UI4, "pb" }, { VT_UI4, "lc" }, { VT_UI4, "lp" }, @@ -251,14 +398,61 @@ static const CNameToPropID g_NameToPropID[] = { VT_UI4, "mt" }, { VT_BOOL, "eos" }, { VT_UI4, "x" }, - { VT_UI4, "reduceSize" } + { VT_UI8, "reduce" }, + { VT_UI8, "expect" }, + { VT_UI8, "cc" }, // "cc" in v23, "b" in v22.01 + { VT_UI4, "check" }, + { VT_BSTR, "filter" }, + { VT_UI8, "memuse" }, + { VT_UI8, "aff" }, + { VT_UI4, "offset" }, + { VT_UI4, "zhb" } + /* + , + // { VT_UI4, "zhc" }, + // { VT_UI4, "zhd" }, + // { VT_UI4, "zcb" }, + { VT_UI4, "dc" }, + { VT_UI4, "zx" }, + { VT_UI4, "zf" }, + { VT_UI4, "zmml" }, + { VT_UI4, "zov" }, + { VT_BOOL, "zmfr" }, + { VT_BOOL, "zle" }, // long enable + // { VT_UI4, "zldb" }, + { VT_UI4, "zld" }, + { VT_UI4, "zlhb" }, + { VT_UI4, "zlmml" }, + { VT_UI4, "zlbb" }, + { VT_UI4, "zlhrb" }, + { VT_BOOL, "zwus" }, + { VT_BOOL, "zshp" }, + { VT_BOOL, "zshs" }, + { VT_BOOL, "zshe" }, + { VT_BOOL, "zshg" }, + { VT_UI4, "zpsm" } + */ + // { VT_UI4, "mcb" }, // mc log version + // { VT_UI4, "ztlen" }, // fb ? }; +/* +#if defined(static_assert) || (defined(__cplusplus) && __cplusplus >= 200410L) || (defined(_MSC_VER) && _MSC_VER >= 1600) + +#if (defined(__cplusplus) && __cplusplus < 201103L) \ + && defined(__clang__) && __clang_major__ >= 4 +#pragma GCC diagnostic ignored "-Wc11-extensions" +#endif + static_assert(Z7_ARRAY_SIZE(g_NameToPropID) == NCoderPropID::k_NUM_DEFINED, + "g_NameToPropID doesn't match NCoderPropID enum"); +#endif +*/ + static int FindPropIdExact(const UString &name) { - for (unsigned i = 0; i < ARRAY_SIZE(g_NameToPropID); i++) + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_NameToPropID); i++) if (StringsAreEqualNoCase_Ascii(name, g_NameToPropID[i].Name)) - return i; + return (int)i; return -1; } @@ -269,6 +463,13 @@ static bool ConvertProperty(const PROPVARIANT &srcProp, VARTYPE varType, NCOM::C destProp = srcProp; return true; } + + if (varType == VT_UI8 && srcProp.vt == VT_UI4) + { + destProp = (UInt64)srcProp.ulVal; + return true; + } + if (varType == VT_BOOL) { bool res; @@ -311,8 +512,8 @@ static void SplitParam(const UString ¶m, UString &name, UString &value) int eqPos = param.Find(L'='); if (eqPos >= 0) { - name.SetFrom(param, eqPos); - value = param.Ptr(eqPos + 1); + name.SetFrom(param, (unsigned)eqPos); + value = param.Ptr((unsigned)(eqPos + 1)); return; } unsigned i; @@ -333,7 +534,12 @@ static bool IsLogSizeProp(PROPID propid) case NCoderPropID::kDictionarySize: case NCoderPropID::kUsedMemorySize: case NCoderPropID::kBlockSize: - case NCoderPropID::kReduceSize: + case NCoderPropID::kBlockSize2: + /* + case NCoderPropID::kChainSize: + case NCoderPropID::kLdmWindowSize: + */ + // case NCoderPropID::kReduceSize: return true; } return false; @@ -343,14 +549,19 @@ HRESULT CMethodProps::SetParam(const UString &name, const UString &value) { int index = FindPropIdExact(name); if (index < 0) - return E_INVALIDARG; + { + // 'b' was used as NCoderPropID::kBlockSize2 before v23 + if (!name.IsEqualTo_Ascii_NoCase("b") || value.Find(L':') >= 0) + return E_INVALIDARG; + index = NCoderPropID::kBlockSize2; + } const CNameToPropID &nameToPropID = g_NameToPropID[(unsigned)index]; CProp prop; - prop.Id = index; + prop.Id = (unsigned)index; if (IsLogSizeProp(prop.Id)) { - RINOK(StringToDictSize(value, prop.Value)); + RINOK(StringToDictSize(value, prop.Value)) } else { @@ -366,9 +577,22 @@ HRESULT CMethodProps::SetParam(const UString &name, const UString &value) } else if (!value.IsEmpty()) { - UInt32 number; - if (ParseStringToUInt32(value, number) == value.Len()) - propValue = number; + if (nameToPropID.VarType == VT_UI4) + { + UInt32 number; + if (ParseStringToUInt32(value, number) == value.Len()) + propValue = number; + else + propValue = value; + } + else if (nameToPropID.VarType == VT_UI8) + { + UInt64 number; + if (ParseStringToUInt64(value, number) == value.Len()) + propValue = number; + else + propValue = value; + } else propValue = value; } @@ -388,7 +612,7 @@ HRESULT CMethodProps::ParseParamsFromString(const UString &srcString) const UString ¶m = params[i]; UString name, value; SplitParam(param, name, value); - RINOK(SetParam(name, value)); + RINOK(SetParam(name, value)) } return S_OK; } @@ -409,16 +633,16 @@ HRESULT CMethodProps::ParseParamsFromPROPVARIANT(const UString &realName, const } // {realName}=value - int index = FindPropIdExact(realName); + const int index = FindPropIdExact(realName); if (index < 0) return E_INVALIDARG; const CNameToPropID &nameToPropID = g_NameToPropID[(unsigned)index]; CProp prop; - prop.Id = index; + prop.Id = (unsigned)index; if (IsLogSizeProp(prop.Id)) { - RINOK(PROPVARIANT_to_DictSize(value, prop.Value)); + RINOK(PROPVARIANT_to_DictSize(value, prop.Value)) } else { @@ -429,6 +653,59 @@ HRESULT CMethodProps::ParseParamsFromPROPVARIANT(const UString &realName, const return S_OK; } + +static UInt64 GetMemoryUsage_LZMA(UInt32 dict, bool isBt, UInt32 numThreads) +{ + UInt32 hs = dict - 1; + hs |= (hs >> 1); + hs |= (hs >> 2); + hs |= (hs >> 4); + hs |= (hs >> 8); + hs >>= 1; + if (hs >= (1 << 24)) + hs >>= 1; + hs |= (1 << 16) - 1; + // if (numHashBytes >= 5) + if (!isBt) + hs |= (256 << 10) - 1; + hs++; + UInt64 size1 = (UInt64)hs * 4; + size1 += (UInt64)dict * 4; + if (isBt) + size1 += (UInt64)dict * 4; + size1 += (2 << 20); + + if (numThreads > 1 && isBt) + size1 += (2 << 20) + (4 << 20); + return size1; +} + +static const UInt32 kLzmaMaxDictSize = (UInt32)15 << 28; + +UInt64 CMethodProps::Get_Lzma_MemUsage(bool addSlidingWindowSize) const +{ + const UInt64 dicSize = Get_Lzma_DicSize(); + const bool isBt = Get_Lzma_MatchFinder_IsBt(); + const UInt32 dict32 = (dicSize >= kLzmaMaxDictSize ? kLzmaMaxDictSize : (UInt32)dicSize); + const UInt32 numThreads = Get_Lzma_NumThreads(); + UInt64 size = GetMemoryUsage_LZMA(dict32, isBt, numThreads); + + if (addSlidingWindowSize) + { + const UInt32 kBlockSizeMax = (UInt32)0 - (UInt32)(1 << 16); + UInt64 blockSize = (UInt64)dict32 + (1 << 16) + + (numThreads > 1 ? (1 << 20) : 0); + blockSize += (blockSize >> (blockSize < ((UInt32)1 << 30) ? 1 : 2)); + if (blockSize >= kBlockSizeMax) + blockSize = kBlockSizeMax; + size += blockSize; + } + return size; +} + + + + HRESULT COneMethodInfo::ParseMethodFromString(const UString &s) { MethodName.Empty(); @@ -436,14 +713,14 @@ HRESULT COneMethodInfo::ParseMethodFromString(const UString &s) { UString temp = s; if (splitPos >= 0) - temp.DeleteFrom(splitPos); + temp.DeleteFrom((unsigned)splitPos); if (!temp.IsAscii()) return E_INVALIDARG; MethodName.SetFromWStr_if_Ascii(temp); } if (splitPos < 0) return S_OK; - PropsString = s.Ptr(splitPos + 1); + PropsString = s.Ptr((unsigned)(splitPos + 1)); return ParseParamsFromString(PropsString); } @@ -454,5 +731,7 @@ HRESULT COneMethodInfo::ParseMethodFromPROPVARIANT(const UString &realName, cons // -m{N}=method if (value.vt != VT_BSTR) return E_INVALIDARG; - return ParseMethodFromString(value.bstrVal); + UString s; + s = value.bstrVal; + return ParseMethodFromString(s); } diff --git a/3rdparty/lzma/CPP/7zip/Common/MethodProps.h b/3rdparty/lzma/CPP/7zip/Common/MethodProps.h index 765e425df6d..3c332d6af48 100644 --- a/3rdparty/lzma/CPP/7zip/Common/MethodProps.h +++ b/3rdparty/lzma/CPP/7zip/Common/MethodProps.h @@ -1,20 +1,49 @@ // MethodProps.h -#ifndef __7Z_METHOD_PROPS_H -#define __7Z_METHOD_PROPS_H +#ifndef ZIP7_INC_7Z_METHOD_PROPS_H +#define ZIP7_INC_7Z_METHOD_PROPS_H #include "../../Common/MyString.h" +#include "../../Common/Defs.h" + +#include "../../Windows/Defs.h" #include "../../Windows/PropVariant.h" #include "../ICoder.h" -bool StringToBool(const UString &s, bool &res); +// UInt64 GetMemoryUsage_LZMA(UInt32 dict, bool isBt, UInt32 numThreads); + +inline UInt64 Calc_From_Val_Percents_Less100(UInt64 val, UInt64 percents) +{ + if (percents == 0) + return 0; + if (val <= (UInt64)(Int64)-1 / percents) + return val * percents / 100; + return val / 100 * percents; +} + +UInt64 Calc_From_Val_Percents(UInt64 val, UInt64 percents); + +bool StringToBool(const wchar_t *s, bool &res); HRESULT PROPVARIANT_to_bool(const PROPVARIANT &prop, bool &dest); unsigned ParseStringToUInt32(const UString &srcString, UInt32 &number); + +/* +if (name.IsEmpty() && prop.vt == VT_EMPTY), it doesn't change (resValue) and returns S_OK. + So you must set (resValue) for default value before calling */ HRESULT ParsePropToUInt32(const UString &name, const PROPVARIANT &prop, UInt32 &resValue); -HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads); +/* input: (numThreads = the_number_of_processors) */ +HRESULT ParseMtProp2(const UString &name, const PROPVARIANT &prop, UInt32 &numThreads, bool &force); + +inline HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 numCPUs, UInt32 &numThreads) +{ + bool forced = false; + numThreads = numCPUs; + return ParseMtProp2(name, prop, numThreads, forced); +} + struct CProp { @@ -38,7 +67,9 @@ struct CProps return false; } - void AddProp32(PROPID propid, UInt32 level); + void AddProp32(PROPID propid, UInt32 val); + + void AddPropBool(PROPID propid, bool val); void AddProp_Ascii(PROPID propid, const char *s) { @@ -48,33 +79,45 @@ struct CProps prop.Value = s; } - HRESULT SetCoderProps(ICompressSetCoderProperties *scp, const UInt64 *dataSizeReduce) const; + HRESULT SetCoderProps(ICompressSetCoderProperties *scp, const UInt64 *dataSizeReduce = NULL) const; + HRESULT SetCoderProps_DSReduce_Aff(ICompressSetCoderProperties *scp, const UInt64 *dataSizeReduce, const UInt64 *affinity) const; }; class CMethodProps: public CProps { HRESULT SetParam(const UString &name, const UString &value); public: - int GetLevel() const; + unsigned GetLevel() const; int Get_NumThreads() const { - int i = FindProp(NCoderPropID::kNumThreads); + const int i = FindProp(NCoderPropID::kNumThreads); if (i >= 0) - if (Props[i].Value.vt == VT_UI4) - return (int)Props[i].Value.ulVal; + { + const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value; + if (val.vt == VT_UI4) + return (int)val.ulVal; + } return -1; } - bool Get_DicSize(UInt32 &res) const + bool Get_DicSize(UInt64 &res) const { res = 0; - int i = FindProp(NCoderPropID::kDictionarySize); + const int i = FindProp(NCoderPropID::kDictionarySize); if (i >= 0) - if (Props[i].Value.vt == VT_UI4) + { + const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value; + if (val.vt == VT_UI4) + { + res = val.ulVal; + return true; + } + if (val.vt == VT_UI8) { - res = Props[i].Value.ulVal; + res = val.uhVal.QuadPart; return true; } + } return false; } @@ -84,19 +127,50 @@ public: { int i = FindProp(NCoderPropID::kAlgorithm); if (i >= 0) - if (Props[i].Value.vt == VT_UI4) - return Props[i].Value.ulVal; + { + const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value; + if (val.vt == VT_UI4) + return val.ulVal; + } return GetLevel() >= 5 ? 1 : 0; } - UInt32 Get_Lzma_DicSize() const + UInt64 Get_Lzma_DicSize() const + { + UInt64 v; + if (Get_DicSize(v)) + return v; + const unsigned level = GetLevel(); + const UInt32 dictSize = + ( level <= 3 ? ((UInt32)1 << (level * 2 + 16)) : + ( level <= 6 ? ((UInt32)1 << (level + 19)) : + ( level <= 7 ? ((UInt32)1 << 25) : ((UInt32)1 << 26) + ))); + return dictSize; + } + + bool Get_Lzma_MatchFinder_IsBt() const { - int i = FindProp(NCoderPropID::kDictionarySize); + const int i = FindProp(NCoderPropID::kMatchFinder); if (i >= 0) - if (Props[i].Value.vt == VT_UI4) - return Props[i].Value.ulVal; - int level = GetLevel(); - return level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26)); + { + const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value; + if (val.vt == VT_BSTR) + return ((val.bstrVal[0] | 0x20) != 'h'); // check for "hc" + } + return GetLevel() >= 5; + } + + bool Get_Lzma_Eos() const + { + const int i = FindProp(NCoderPropID::kEndMarker); + if (i >= 0) + { + const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value; + if (val.vt == VT_BOOL) + return VARIANT_BOOLToBool(val.boolVal); + } + return false; } bool Are_Lzma_Model_Props_Defined() const @@ -107,18 +181,68 @@ public: return false; } - UInt32 Get_Lzma_NumThreads(bool &fixedNumber) const + UInt32 Get_Lzma_NumThreads() const { - fixedNumber = false; + if (Get_Lzma_Algo() == 0) + return 1; int numThreads = Get_NumThreads(); if (numThreads >= 0) - { - fixedNumber = true; return numThreads < 2 ? 1 : 2; + return 2; + } + + UInt64 Get_Lzma_MemUsage(bool addSlidingWindowSize) const; + + /* returns -1, if numThreads is unknown */ + int Get_Xz_NumThreads(UInt32 &lzmaThreads) const + { + lzmaThreads = 1; + int numThreads = Get_NumThreads(); + if (numThreads >= 0 && numThreads <= 1) + return 1; + if (Get_Lzma_Algo() != 0) + lzmaThreads = 2; + return numThreads; + } + + UInt64 GetProp_BlockSize(PROPID id) const + { + const int i = FindProp(id); + if (i >= 0) + { + const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value; + if (val.vt == VT_UI4) { return val.ulVal; } + if (val.vt == VT_UI8) { return val.uhVal.QuadPart; } } - return Get_Lzma_Algo() == 0 ? 1 : 2; + return 0; } + UInt64 Get_Xz_BlockSize() const + { + { + UInt64 blockSize1 = GetProp_BlockSize(NCoderPropID::kBlockSize); + UInt64 blockSize2 = GetProp_BlockSize(NCoderPropID::kBlockSize2); + UInt64 minSize = MyMin(blockSize1, blockSize2); + if (minSize != 0) + return minSize; + UInt64 maxSize = MyMax(blockSize1, blockSize2); + if (maxSize != 0) + return maxSize; + } + const UInt32 kMinSize = (UInt32)1 << 20; + const UInt32 kMaxSize = (UInt32)1 << 28; + const UInt64 dictSize = Get_Lzma_DicSize(); + /* lzma2 code uses fake 4 GiB to calculate ChunkSize. So we do same */ + UInt64 blockSize = (UInt64)dictSize << 2; + if (blockSize < kMinSize) blockSize = kMinSize; + if (blockSize > kMaxSize) blockSize = kMaxSize; + if (blockSize < dictSize) blockSize = dictSize; + blockSize += (kMinSize - 1); + blockSize &= ~(UInt64)(kMinSize - 1); + return blockSize; + } + + UInt32 Get_BZip2_NumThreads(bool &fixedNumber) const { fixedNumber = false; @@ -127,37 +251,47 @@ public: { fixedNumber = true; if (numThreads < 1) return 1; - if (numThreads > 64) return 64; - return numThreads; + const unsigned kNumBZip2ThreadsMax = 64; + if ((unsigned)numThreads > kNumBZip2ThreadsMax) return kNumBZip2ThreadsMax; + return (unsigned)numThreads; } return 1; } UInt32 Get_BZip2_BlockSize() const { - int i = FindProp(NCoderPropID::kDictionarySize); + const int i = FindProp(NCoderPropID::kDictionarySize); if (i >= 0) - if (Props[i].Value.vt == VT_UI4) + { + const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value; + if (val.vt == VT_UI4) { - UInt32 blockSize = Props[i].Value.ulVal; + UInt32 blockSize = val.ulVal; const UInt32 kDicSizeMin = 100000; const UInt32 kDicSizeMax = 900000; if (blockSize < kDicSizeMin) blockSize = kDicSizeMin; if (blockSize > kDicSizeMax) blockSize = kDicSizeMax; return blockSize; } - int level = GetLevel(); + } + const unsigned level = GetLevel(); return 100000 * (level >= 5 ? 9 : (level >= 1 ? level * 2 - 1: 1)); } - UInt32 Get_Ppmd_MemSize() const + UInt64 Get_Ppmd_MemSize() const { - int i = FindProp(NCoderPropID::kUsedMemorySize); + const int i = FindProp(NCoderPropID::kUsedMemorySize); if (i >= 0) - if (Props[i].Value.vt == VT_UI4) - return Props[i].Value.ulVal; - int level = GetLevel(); - return level >= 9 ? (192 << 20) : ((UInt32)1 << (level + 19)); + { + const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value; + if (val.vt == VT_UI4) + return val.ulVal; + if (val.vt == VT_UI8) + return val.uhVal.QuadPart; + } + const unsigned level = GetLevel(); + const UInt32 mem = (UInt32)1 << (level + 19); + return mem; } void AddProp_Level(UInt32 level) @@ -170,6 +304,23 @@ public: AddProp32(NCoderPropID::kNumThreads, numThreads); } + void AddProp_EndMarker_if_NotFound(bool eos) + { + if (FindProp(NCoderPropID::kEndMarker) < 0) + AddPropBool(NCoderPropID::kEndMarker, eos); + } + + void AddProp_BlockSize2(UInt64 blockSize2) + { + if (FindProp(NCoderPropID::kBlockSize2) < 0) + { + CProp &prop = Props.AddNew(); + prop.IsOptional = true; + prop.Id = NCoderPropID::kBlockSize2; + prop.Value = blockSize2; + } + } + HRESULT ParseParamsFromString(const UString &srcString); HRESULT ParseParamsFromPROPVARIANT(const UString &realName, const PROPVARIANT &value); }; diff --git a/3rdparty/lzma/CPP/7zip/Common/MultiOutStream.cpp b/3rdparty/lzma/CPP/7zip/Common/MultiOutStream.cpp new file mode 100644 index 00000000000..8efb977fdba --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/Common/MultiOutStream.cpp @@ -0,0 +1,849 @@ +// MultiOutStream.cpp + +#include "StdAfx.h" + +// #define DEBUG_VOLUMES + +#ifdef DEBUG_VOLUMES +#include <stdio.h> + #define PRF(x) x; +#else + #define PRF(x) +#endif + +#include "../../Common/ComTry.h" + +#include "../../Windows/FileDir.h" +#include "../../Windows/FileFind.h" +#include "../../Windows/System.h" + +#include "MultiOutStream.h" + +using namespace NWindows; +using namespace NFile; +using namespace NDir; + +static const unsigned k_NumVols_MAX = k_VectorSizeMax - 1; + // 2; // for debug + +/* +#define UPDATE_HRES(hres, x) \ + { const HRESULT res2 = (x); if (hres == SZ_OK) hres = res2; } +*/ + +HRESULT CMultiOutStream::Destruct() +{ + COM_TRY_BEGIN + HRESULT hres = S_OK; + HRESULT hres3 = S_OK; + + while (!Streams.IsEmpty()) + { + try + { + HRESULT hres2; + if (NeedDelete) + { + /* we could call OptReOpen_and_SetSize() to test that we try to delete correct file, + but we cannot guarantee that (RealSize) will be correct after Write() or another failures. + And we still want to delete files even for such cases. + So we don't check for OptReOpen_and_SetSize() here: */ + // if (OptReOpen_and_SetSize(Streams.Size() - 1, 0) == S_OK) + hres2 = CloseStream_and_DeleteFile(Streams.Size() - 1); + } + else + { + hres2 = CloseStream(Streams.Size() - 1); + } + if (hres == S_OK) + hres = hres2; + } + catch(...) + { + hres3 = E_OUTOFMEMORY; + } + + { + /* Stream was released in CloseStream_*() above already, and it was removed from linked list + it's some unexpected case, if Stream is still attached here. + So the following code is optional: */ + CVolStream &s = Streams.Back(); + if (s.Stream) + { + if (hres3 == S_OK) + hres3 = E_FAIL; + s.Stream.Detach(); + /* it will be not failure, even if we call RemoveFromLinkedList() + twice for same CVolStream in this Destruct() function */ + RemoveFromLinkedList(Streams.Size() - 1); + } + } + Streams.DeleteBack(); + // Delete_LastStream_Records(); + } + + if (hres == S_OK) + hres = hres3; + if (hres == S_OK && NumListItems != 0) + hres = E_FAIL; + return hres; + COM_TRY_END +} + + +CMultiOutStream::~CMultiOutStream() +{ + // we try to avoid exception in destructors + Destruct(); +} + + +void CMultiOutStream::Init(const CRecordVector<UInt64> &sizes) +{ + Streams.Clear(); + InitLinkedList(); + Sizes = sizes; + NeedDelete = true; + MTime_Defined = false; + FinalVol_WasReopen = false; + NumOpenFiles_AllowedMax = NSystem::Get_File_OPEN_MAX_Reduced_for_3_tasks(); + + _streamIndex = 0; + _offsetPos = 0; + _absPos = 0; + _length = 0; + _absLimit = (UInt64)(Int64)-1; + + _restrict_Begin = 0; + _restrict_End = (UInt64)(Int64)-1; + _restrict_Global = 0; + + UInt64 sum = 0; + unsigned i = 0; + for (i = 0; i < Sizes.Size(); i++) + { + if (i >= k_NumVols_MAX) + { + _absLimit = sum; + break; + } + const UInt64 size = Sizes[i]; + const UInt64 next = sum + size; + if (next < sum) + break; + sum = next; + } + + // if (Sizes.IsEmpty()) throw "no volume sizes"; + const UInt64 size = Sizes.Back(); + if (size == 0) + throw "zero size last volume"; + + if (i == Sizes.Size()) + if ((_absLimit - sum) / size >= (k_NumVols_MAX - i)) + _absLimit = sum + (k_NumVols_MAX - i) * size; +} + + +/* IsRestricted(): + we must call only if volume is full (s.RealSize==VolSize) or finished. + the function doesn't use VolSize and it uses s.RealSize instead. + it returns true : if stream is restricted, and we can't close that stream + it returns false : if there is no restriction, and we can close that stream + Note: (RealSize == 0) (empty volume) on restriction bounds are supposed as non-restricted +*/ +bool CMultiOutStream::IsRestricted(const CVolStream &s) const +{ + if (s.Start < _restrict_Global) + return true; + if (_restrict_Begin == _restrict_End) + return false; + if (_restrict_Begin <= s.Start) + return _restrict_End > s.Start; + return _restrict_Begin < s.Start + s.RealSize; +} + +/* +// this function check also _length and volSize +bool CMultiOutStream::IsRestricted_for_Close(unsigned index) const +{ + const CVolStream &s = Streams[index]; + if (_length <= s.Start) // we don't close streams after the end, because we still can write them later + return true; + // (_length > s.Start) + const UInt64 volSize = GetVolSize_for_Stream(index); + if (volSize == 0) + return IsRestricted_Empty(s); + if (_length - s.Start < volSize) + return true; + return IsRestricted(s); +} +*/ + +FString CMultiOutStream::GetFilePath(unsigned index) +{ + FString name; + name.Add_UInt32(index + 1); + while (name.Len() < 3) + name.InsertAtFront(FTEXT('0')); + name.Insert(0, Prefix); + return name; +} + + +// we close stream, but we still keep item in Streams[] vector +HRESULT CMultiOutStream::CloseStream(unsigned index) +{ + CVolStream &s = Streams[index]; + if (s.Stream) + { + RINOK(s.StreamSpec->Close()) + // the following two commands must be called together: + s.Stream.Release(); + RemoveFromLinkedList(index); + } + return S_OK; +} + + +// we close stream and delete file, but we still keep item in Streams[] vector +HRESULT CMultiOutStream::CloseStream_and_DeleteFile(unsigned index) +{ + PRF(printf("\n====== %u, CloseStream_AndDelete \n", index)); + RINOK(CloseStream(index)) + FString path = GetFilePath(index); + path += Streams[index].Postfix; + // we can checki that file exist + // if (NFind::DoesFileExist_Raw(path)) + if (!DeleteFileAlways(path)) + return GetLastError_noZero_HRESULT(); + return S_OK; +} + + +HRESULT CMultiOutStream::CloseStream_and_FinalRename(unsigned index) +{ + PRF(printf("\n====== %u, CloseStream_and_FinalRename \n", index)); + CVolStream &s = Streams[index]; + // HRESULT res = S_OK; + bool mtime_WasSet = false; + if (MTime_Defined && s.Stream) + { + if (s.StreamSpec->SetMTime(&MTime)) + mtime_WasSet = true; + // else res = GetLastError_noZero_HRESULT(); + } + + RINOK(CloseStream(index)) + if (s.Postfix.IsEmpty()) // if Postfix is empty, the path is already final + return S_OK; + const FString path = GetFilePath(index); + FString tempPath = path; + tempPath += s.Postfix; + + if (MTime_Defined && !mtime_WasSet) + { + if (!SetDirTime(tempPath, NULL, NULL, &MTime)) + { + // res = GetLastError_noZero_HRESULT(); + } + } + if (!MyMoveFile(tempPath, path)) + return GetLastError_noZero_HRESULT(); + /* we clear CVolStream::Postfix. So we will not use Temp path + anymore for this stream, and we will work only with final path */ + s.Postfix.Empty(); + // we can ignore set_mtime error or we can return it + return S_OK; + // return res; +} + + +HRESULT CMultiOutStream::PrepareToOpenNew() +{ + if (NumListItems < NumOpenFiles_AllowedMax) + return S_OK; + /* when we create zip archive: in most cases we need only starting + data of restricted region for rewriting zip's local header. + So here we close latest created volume (from Head), and we try to + keep oldest volumes that will be used for header rewriting later. */ + const int index = Head; + if (index == -1) + return E_FAIL; + PRF(printf("\n== %u, PrepareToOpenNew::CloseStream, NumListItems =%u \n", index, NumListItems)); + /* we don't expect non-restricted stream here in normal cases (if _restrict_Global was not changed). + if there was non-restricted stream, it should be closed before */ + // if (!IsRestricted_for_Close(index)) return CloseStream_and_FinalRename(index); + return CloseStream((unsigned)index); +} + + +HRESULT CMultiOutStream::CreateNewStream(UInt64 newSize) +{ + PRF(printf("\n== %u, CreateNewStream, size =%u \n", Streams.Size(), (unsigned)newSize)); + + if (Streams.Size() >= k_NumVols_MAX) + return E_INVALIDARG; // E_OUTOFMEMORY + + RINOK(PrepareToOpenNew()) + CVolStream s; + s.StreamSpec = new COutFileStream; + s.Stream = s.StreamSpec; + const FString path = GetFilePath(Streams.Size()); + + if (NFind::DoesFileExist_Raw(path)) + return HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS); + if (!CreateTempFile2(path, false, s.Postfix, &s.StreamSpec->File)) + return GetLastError_noZero_HRESULT(); + + s.Start = GetGlobalOffset_for_NewStream(); + s.Pos = 0; + s.RealSize = 0; + + const unsigned index = Streams.Add(s); + InsertToLinkedList(index); + + if (newSize != 0) + return s.SetSize2(newSize); + return S_OK; +} + + +HRESULT CMultiOutStream::CreateStreams_If_Required(unsigned streamIndex) +{ + // UInt64 lastStreamSize = 0; + for (;;) + { + const unsigned numStreamsBefore = Streams.Size(); + if (streamIndex < numStreamsBefore) + return S_OK; + UInt64 newSize; + if (streamIndex == numStreamsBefore) + { + // it's final volume that will be used for real writing. + /* SetSize(_offsetPos) is not required, + because the file Size will be set later by calling Seek() with Write() */ + newSize = 0; // lastStreamSize; + } + else + { + // it's intermediate volume. So we need full volume size + newSize = GetVolSize_for_Stream(numStreamsBefore); + } + + RINOK(CreateNewStream(newSize)) + + // optional check + if (numStreamsBefore + 1 != Streams.Size()) return E_FAIL; + + if (streamIndex != numStreamsBefore) + { + // it's intermediate volume. So we can close it, if it's non-restricted + bool isRestricted; + { + const CVolStream &s = Streams[numStreamsBefore]; + if (newSize == 0) + isRestricted = IsRestricted_Empty(s); + else + isRestricted = IsRestricted(s); + } + if (!isRestricted) + { + RINOK(CloseStream_and_FinalRename(numStreamsBefore)) + } + } + } +} + + +HRESULT CMultiOutStream::ReOpenStream(unsigned streamIndex) +{ + PRF(printf("\n====== %u, ReOpenStream \n", streamIndex)); + RINOK(PrepareToOpenNew()) + CVolStream &s = Streams[streamIndex]; + + FString path = GetFilePath(streamIndex); + path += s.Postfix; + + s.StreamSpec = new COutFileStream; + s.Stream = s.StreamSpec; + s.Pos = 0; + + HRESULT hres; + if (s.StreamSpec->Open(path, OPEN_EXISTING)) + { + if (s.Postfix.IsEmpty()) + { + /* it's unexpected case that we open finished volume. + It can mean that the code for restriction is incorrect */ + FinalVol_WasReopen = true; + } + UInt64 realSize = 0; + hres = s.StreamSpec->GetSize(&realSize); + if (hres == S_OK) + { + if (realSize == s.RealSize) + { + InsertToLinkedList(streamIndex); + return S_OK; + } + // file size was changed between Close() and ReOpen() + // we must release Stream to be consistent with linked list + hres = E_FAIL; + } + } + else + hres = GetLastError_noZero_HRESULT(); + s.Stream.Release(); + s.StreamSpec = NULL; + return hres; +} + + +/* Sets size of stream, if new size is not equal to old size (RealSize). + If stream was closed and size change is required, it reopens the stream. */ + +HRESULT CMultiOutStream::OptReOpen_and_SetSize(unsigned index, UInt64 size) +{ + CVolStream &s = Streams[index]; + if (size == s.RealSize) + return S_OK; + if (!s.Stream) + { + RINOK(ReOpenStream(index)) + } + PRF(printf("\n== %u, OptReOpen_and_SetSize, size =%u RealSize = %u\n", index, (unsigned)size, (unsigned)s.RealSize)); + // comment it to debug tail after data + return s.SetSize2(size); +} + + +/* +call Normalize_finalMode(false), if _length was changed. + for all streams starting after _length: + - it sets zero size + - it still keeps file open + Note: after _length reducing with CMultiOutStream::SetSize() we can + have very big number of empty streams at the end of Streams[] list. + And Normalize_finalMode() will runs all these empty streams of Streams[] vector. + So it can be ineffective, if we call Normalize_finalMode() many + times after big reducing of (_length). + +call Normalize_finalMode(true) to set final presentations of all streams + for all streams starting after _length: + - it sets zero size + - it removes file + - it removes CVolStream object from Streams[] vector + +Note: we don't remove zero sized first volume, if (_length == 0) +*/ + +HRESULT CMultiOutStream::Normalize_finalMode(bool finalMode) +{ + PRF(printf("\n== Normalize_finalMode: _length =%d \n", (unsigned)_length)); + + unsigned i = Streams.Size(); + + UInt64 offset = 0; + + /* At first we normalize (reduce or increase) the sizes of all existing + streams in Streams[] that can be affected by changed _length. + And we remove tailing zero-size streams, if (finalMode == true) */ + while (i != 0) + { + offset = Streams[--i].Start; // it's last item in Streams[] + // we don't want to remove first volume + if (offset < _length || i == 0) + { + const UInt64 volSize = GetVolSize_for_Stream(i); + UInt64 size = _length - offset; // (size != 0) here + if (size > volSize) + size = volSize; + RINOK(OptReOpen_and_SetSize(i, size)) + if (_length - offset <= volSize) + return S_OK; + // _length - offset > volSize + offset += volSize; + // _length > offset + break; + // UPDATE_HRES(res, OptReOpen_and_SetSize(i, size)); + } + + /* we Set Size of stream to zero even for (finalMode==true), although + that stream will be deleted in next commands */ + // UPDATE_HRES(res, OptReOpen_and_SetSize(i, 0)); + RINOK(OptReOpen_and_SetSize(i, 0)) + if (finalMode) + { + RINOK(CloseStream_and_DeleteFile(i)) + /* CVolStream::Stream was released above already, and it was + removed from linked list. So we don't need to update linked list + structure, when we delete last item in Streams[] */ + Streams.DeleteBack(); + // Delete_LastStream_Records(); + } + } + + /* now we create new zero-filled streams to cover all data up to _length */ + + if (_length == 0) + return S_OK; + + // (offset) is start offset of next stream after existing Streams[] + + for (;;) + { + // _length > offset + const UInt64 volSize = GetVolSize_for_Stream(Streams.Size()); + UInt64 size = _length - offset; // (size != 0) here + if (size > volSize) + size = volSize; + RINOK(CreateNewStream(size)) + if (_length - offset <= volSize) + return S_OK; + // _length - offset > volSize) + offset += volSize; + // _length > offset + } +} + + +HRESULT CMultiOutStream::FinalFlush_and_CloseFiles(unsigned &numTotalVolumesRes) +{ + // at first we remove unused zero-sized streams after _length + HRESULT res = Normalize_finalMode(true); + numTotalVolumesRes = Streams.Size(); + FOR_VECTOR (i, Streams) + { + const HRESULT res2 = CloseStream_and_FinalRename(i); + if (res == S_OK) + res = res2; + } + if (NumListItems != 0 && res == S_OK) + res = E_FAIL; + return res; +} + + +bool CMultiOutStream::SetMTime_Final(const CFiTime &mTime) +{ + // we will set mtime only if new value differs from previous + if (!FinalVol_WasReopen && MTime_Defined && Compare_FiTime(&MTime, &mTime) == 0) + return true; + bool res = true; + FOR_VECTOR (i, Streams) + { + CVolStream &s = Streams[i]; + if (s.Stream) + { + if (!s.StreamSpec->SetMTime(&mTime)) + res = false; + } + else + { + if (!SetDirTime(GetFilePath(i), NULL, NULL, &mTime)) + res = false; + } + } + return res; +} + + +Z7_COM7F_IMF(CMultiOutStream::SetSize(UInt64 newSize)) +{ + COM_TRY_BEGIN + if ((Int64)newSize < 0) + return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; + if (newSize > _absLimit) + { + /* big seek value was sent to SetSize() or to Seek()+Write(). + It can mean one of two situations: + 1) some incorrect code called it with big seek value. + 2) volume size was small, and we have too big number of volumes + */ + /* in Windows SetEndOfFile() can return: + ERROR_NEGATIVE_SEEK: for >= (1 << 63) + ERROR_INVALID_PARAMETER: for > (16 TiB - 64 KiB) + ERROR_DISK_FULL: for <= (16 TiB - 64 KiB) + */ + // return E_FAIL; + // return E_OUTOFMEMORY; + return E_INVALIDARG; + } + + if (newSize > _length) + { + // we don't expect such case. So we just define global restriction */ + _restrict_Global = newSize; + } + else if (newSize < _restrict_Global) + _restrict_Global = newSize; + + PRF(printf("\n== SetSize, size =%u \n", (unsigned)newSize)); + + _length = newSize; + return Normalize_finalMode(false); + + COM_TRY_END +} + + +Z7_COM7F_IMF(CMultiOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) +{ + COM_TRY_BEGIN + if (processedSize) + *processedSize = 0; + if (size == 0) + return S_OK; + + if (_absPos > _length) + { + // it create data only up to _absPos. + // but we still can need additional new streams, if _absPos at range of volume + RINOK(SetSize(_absPos)) + } + + while (size != 0) + { + UInt64 volSize; + { + if (_streamIndex < Sizes.Size() - 1) + { + volSize = Sizes[_streamIndex]; + if (_offsetPos >= volSize) + { + _offsetPos -= volSize; + _streamIndex++; + continue; + } + } + else + { + volSize = Sizes[Sizes.Size() - 1]; + if (_offsetPos >= volSize) + { + const UInt64 v = _offsetPos / volSize; + if (v >= ((UInt32)(Int32)-1) - _streamIndex) + return E_INVALIDARG; + // throw 202208; + _streamIndex += (unsigned)v; + _offsetPos -= (unsigned)v * volSize; + } + if (_streamIndex >= k_NumVols_MAX) + return E_INVALIDARG; + } + } + + // (_offsetPos < volSize) here + + /* we can need to create one or more streams here, + vol_size for some streams is allowed to be 0. + Also we close some new created streams, if they are non-restricted */ + // file Size will be set later by calling Seek() with Write() + + /* the case (_absPos > _length) was processed above with SetSize(_absPos), + so here it's expected. that we can create optional zero-size streams and then _streamIndex */ + RINOK(CreateStreams_If_Required(_streamIndex)) + + CVolStream &s = Streams[_streamIndex]; + + PRF(printf("\n%d, == Write : Pos = %u, RealSize = %u size =%u \n", + _streamIndex, (unsigned)s.Pos, (unsigned)s.RealSize, size)); + + if (!s.Stream) + { + RINOK(ReOpenStream(_streamIndex)) + } + if (_offsetPos != s.Pos) + { + RINOK(s.Stream->Seek((Int64)_offsetPos, STREAM_SEEK_SET, NULL)) + s.Pos = _offsetPos; + } + + UInt32 curSize = size; + { + const UInt64 rem = volSize - _offsetPos; + if (curSize > rem) + curSize = (UInt32)rem; + } + // curSize != 0 + UInt32 realProcessed = 0; + + HRESULT hres = s.Stream->Write(data, curSize, &realProcessed); + + data = (const void *)((const Byte *)data + realProcessed); + size -= realProcessed; + s.Pos += realProcessed; + _offsetPos += realProcessed; + _absPos += realProcessed; + if (_length < _absPos) + _length = _absPos; + if (s.RealSize < _offsetPos) + s.RealSize = _offsetPos; + if (processedSize) + *processedSize += realProcessed; + + if (s.Pos == volSize) + { + bool isRestricted; + if (volSize == 0) + isRestricted = IsRestricted_Empty(s); + else + isRestricted = IsRestricted(s); + if (!isRestricted) + { + const HRESULT res2 = CloseStream_and_FinalRename(_streamIndex); + if (hres == S_OK) + hres = res2; + } + _streamIndex++; + _offsetPos = 0; + } + + RINOK(hres) + if (realProcessed == 0 && curSize != 0) + return E_FAIL; + // break; + } + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(CMultiOutStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) +{ + PRF(printf("\n-- Seek seekOrigin=%u Seek =%u\n", seekOrigin, (unsigned)offset)); + + switch (seekOrigin) + { + case STREAM_SEEK_SET: break; + case STREAM_SEEK_CUR: offset += _absPos; break; + case STREAM_SEEK_END: offset += _length; break; + default: return STG_E_INVALIDFUNCTION; + } + if (offset < 0) + return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; + if ((UInt64)offset != _absPos) + { + _absPos = (UInt64)offset; + _offsetPos = (UInt64)offset; + _streamIndex = 0; + } + if (newPosition) + *newPosition = (UInt64)offset; + return S_OK; +} + + +// result value will be saturated to (UInt32)(Int32)-1 + +unsigned CMultiOutStream::GetStreamIndex_for_Offset(UInt64 offset, UInt64 &relOffset) const +{ + const unsigned last = Sizes.Size() - 1; + for (unsigned i = 0; i < last; i++) + { + const UInt64 size = Sizes[i]; + if (offset < size) + { + relOffset = offset; + return i; + } + offset -= size; + } + const UInt64 size = Sizes[last]; + const UInt64 v = offset / size; + if (v >= ((UInt32)(Int32)-1) - last) + return (UInt32)(Int32)-1; // saturation + relOffset = offset - (unsigned)v * size; + return last + (unsigned)(v); +} + + +Z7_COM7F_IMF(CMultiOutStream::SetRestriction(UInt64 begin, UInt64 end)) +{ + COM_TRY_BEGIN + + // begin = end = 0; // for debug + + PRF(printf("\n==================== CMultiOutStream::SetRestriction %u, %u\n", (unsigned)begin, (unsigned)end)); + if (begin > end) + { + // these value are FAILED values. + return E_FAIL; + // return E_INVALIDARG; + /* + // or we can ignore error with 3 ways: no change, non-restricted, saturation: + end = begin; // non-restricted + end = (UInt64)(Int64)-1; // saturation: + return S_OK; + */ + } + UInt64 b = _restrict_Begin; + UInt64 e = _restrict_End; + _restrict_Begin = begin; + _restrict_End = end; + + if (b == e) // if there were no restriction before + return S_OK; // no work to derestrict now. + + /* [b, e) is previous restricted region. So all volumes that + intersect that [b, e) region are candidats for derestriction */ + + if (begin != end) // if there is new non-empty restricted region + { + /* Now we will try to reduce or change (b) and (e) bounds + to reduce main loop that checks volumes for derestriction. + We still use one big derestriction region in main loop, although + in some cases we could have two smaller derestriction regions. + Also usually restriction region cannot move back from previous start position, + so (b <= begin) is expected here for normal cases */ + if (b == begin) // if same low bounds + b = end; // we need to derestrict only after the end of new restricted region + if (e == end) // if same high bounds + e = begin; // we need to derestrict only before the begin of new restricted region + } + + if (b > e) // || b == (UInt64)(Int64)-1 + return S_OK; + + /* Here we close finished volumes that are not restricted anymore. + We close (low number) volumes at first. */ + + UInt64 offset; + unsigned index = GetStreamIndex_for_Offset(b, offset); + + for (; index < Streams.Size(); index++) + { + { + const CVolStream &s = Streams[index]; + if (_length <= s.Start) + break; // we don't close streams after _length + // (_length > s.Start) + const UInt64 volSize = GetVolSize_for_Stream(index); + if (volSize == 0) + { + if (e < s.Start) + break; + // we don't close empty stream, if next byte [s.Start, s.Start] is restricted + if (IsRestricted_Empty(s)) + continue; + } + else + { + if (e <= s.Start) + break; + // we don't close non full streams + if (_length - s.Start < volSize) + break; + // (volSize == s.RealSize) is expected here. So no need to check it + // if (volSize != s.RealSize) break; + if (IsRestricted(s)) + continue; + } + } + RINOK(CloseStream_and_FinalRename(index)) + } + + return S_OK; + COM_TRY_END +} diff --git a/3rdparty/lzma/CPP/7zip/Common/MultiOutStream.h b/3rdparty/lzma/CPP/7zip/Common/MultiOutStream.h new file mode 100644 index 00000000000..2fb78112ec3 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/Common/MultiOutStream.h @@ -0,0 +1,160 @@ +// MultiOutStream.h + +#ifndef ZIP7_INC_MULTI_OUT_STREAM_H +#define ZIP7_INC_MULTI_OUT_STREAM_H + +#include "FileStreams.h" + +Z7_CLASS_IMP_COM_2( + CMultiOutStream + , IOutStream + , IStreamSetRestriction +) + Z7_IFACE_COM7_IMP(ISequentialOutStream) + + Z7_CLASS_NO_COPY(CMultiOutStream) + + struct CVolStream + { + COutFileStream *StreamSpec; + CMyComPtr<IOutStream> Stream; + UInt64 Start; // start pos of current Stream in global stream + UInt64 Pos; // pos in current Stream + UInt64 RealSize; + int Next; // next older + int Prev; // prev newer + AString Postfix; + + HRESULT SetSize2(UInt64 size) + { + const HRESULT res = Stream->SetSize(size); + if (res == SZ_OK) + RealSize = size; + return res; + } + }; + + unsigned _streamIndex; // (_streamIndex >= Stream.Size()) is allowed in some internal code + UInt64 _offsetPos; // offset relative to Streams[_streamIndex] volume. (_offsetPos >= volSize is allowed) + UInt64 _absPos; + UInt64 _length; // virtual Length + UInt64 _absLimit; + + CObjectVector<CVolStream> Streams; + CRecordVector<UInt64> Sizes; + + UInt64 _restrict_Begin; + UInt64 _restrict_End; + UInt64 _restrict_Global; + + unsigned NumOpenFiles_AllowedMax; + + // ----- Double Linked List ----- + + unsigned NumListItems; + int Head; // newest + int Tail; // oldest + + void InitLinkedList() + { + Head = -1; + Tail = -1; + NumListItems = 0; + } + + void InsertToLinkedList(unsigned index) + { + { + CVolStream &node = Streams[index]; + node.Next = Head; + node.Prev = -1; + } + if (Head != -1) + Streams[(unsigned)Head].Prev = (int)index; + else + { + // if (Tail != -1) throw 1; + Tail = (int)index; + } + Head = (int)index; + NumListItems++; + } + + void RemoveFromLinkedList(unsigned index) + { + CVolStream &s = Streams[index]; + if (s.Next != -1) Streams[(unsigned)s.Next].Prev = s.Prev; else Tail = s.Prev; + if (s.Prev != -1) Streams[(unsigned)s.Prev].Next = s.Next; else Head = s.Next; + s.Next = -1; // optional + s.Prev = -1; // optional + NumListItems--; + } + + /* + void Delete_LastStream_Records() + { + if (Streams.Back().Stream) + RemoveFromLinkedList(Streams.Size() - 1); + Streams.DeleteBack(); + } + */ + + UInt64 GetVolSize_for_Stream(unsigned i) const + { + const unsigned last = Sizes.Size() - 1; + return Sizes[i < last ? i : last]; + } + UInt64 GetGlobalOffset_for_NewStream() const + { + return Streams.Size() == 0 ? 0: + Streams.Back().Start + + GetVolSize_for_Stream(Streams.Size() - 1); + } + unsigned GetStreamIndex_for_Offset(UInt64 offset, UInt64 &relOffset) const; + bool IsRestricted(const CVolStream &s) const; + bool IsRestricted_Empty(const CVolStream &s) const + { + // (s) must be stream that has (VolSize == 0). + // we treat empty stream as restricted, if next byte is restricted. + if (s.Start < _restrict_Global) + return true; + return + (_restrict_Begin != _restrict_End) + && (_restrict_Begin <= s.Start) + && (_restrict_Begin == s.Start || _restrict_End > s.Start); + } + // bool IsRestricted_for_Close(unsigned index) const; + FString GetFilePath(unsigned index); + + HRESULT CloseStream(unsigned index); + HRESULT CloseStream_and_DeleteFile(unsigned index); + HRESULT CloseStream_and_FinalRename(unsigned index); + + HRESULT PrepareToOpenNew(); + HRESULT CreateNewStream(UInt64 newSize); + HRESULT CreateStreams_If_Required(unsigned streamIndex); + HRESULT ReOpenStream(unsigned streamIndex); + HRESULT OptReOpen_and_SetSize(unsigned index, UInt64 size); + + HRESULT Normalize_finalMode(bool finalMode); +public: + FString Prefix; + CFiTime MTime; + bool MTime_Defined; + bool FinalVol_WasReopen; + bool NeedDelete; + + CMultiOutStream() {} + ~CMultiOutStream(); + void Init(const CRecordVector<UInt64> &sizes); + bool SetMTime_Final(const CFiTime &mTime); + UInt64 GetSize() const { return _length; } + /* it makes final flushing, closes open files and renames to final name if required + but it still keeps Streams array of all closed files. + So we still can delete all files later, if required */ + HRESULT FinalFlush_and_CloseFiles(unsigned &numTotalVolumesRes); + // Destruct object without exceptions + HRESULT Destruct(); +}; + +#endif diff --git a/3rdparty/lzma/CPP/7zip/Common/OffsetStream.cpp b/3rdparty/lzma/CPP/7zip/Common/OffsetStream.cpp index 368d39b6514..a6b005e4ff6 100644 --- a/3rdparty/lzma/CPP/7zip/Common/OffsetStream.cpp +++ b/3rdparty/lzma/CPP/7zip/Common/OffsetStream.cpp @@ -2,38 +2,36 @@ #include "StdAfx.h" -#include "../../Common/Defs.h" - #include "OffsetStream.h" HRESULT COffsetOutStream::Init(IOutStream *stream, UInt64 offset) { _offset = offset; _stream = stream; - return _stream->Seek(offset, STREAM_SEEK_SET, NULL); + return _stream->Seek((Int64)offset, STREAM_SEEK_SET, NULL); } -STDMETHODIMP COffsetOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(COffsetOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { return _stream->Write(data, size, processedSize); } -STDMETHODIMP COffsetOutStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(COffsetOutStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { - UInt64 absoluteNewPosition; if (seekOrigin == STREAM_SEEK_SET) { if (offset < 0) return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; offset += _offset; } - HRESULT result = _stream->Seek(offset, seekOrigin, &absoluteNewPosition); + UInt64 absoluteNewPosition = 0; // =0 for gcc-10 + const HRESULT result = _stream->Seek(offset, seekOrigin, &absoluteNewPosition); if (newPosition) *newPosition = absoluteNewPosition - _offset; return result; } -STDMETHODIMP COffsetOutStream::SetSize(UInt64 newSize) +Z7_COM7F_IMF(COffsetOutStream::SetSize(UInt64 newSize)) { return _stream->SetSize(_offset + newSize); } diff --git a/3rdparty/lzma/CPP/7zip/Common/OffsetStream.h b/3rdparty/lzma/CPP/7zip/Common/OffsetStream.h index 9074a24e031..9bd554cc8b6 100644 --- a/3rdparty/lzma/CPP/7zip/Common/OffsetStream.h +++ b/3rdparty/lzma/CPP/7zip/Common/OffsetStream.h @@ -1,26 +1,22 @@ // OffsetStream.h -#ifndef __OFFSET_STREAM_H -#define __OFFSET_STREAM_H +#ifndef ZIP7_INC_OFFSET_STREAM_H +#define ZIP7_INC_OFFSET_STREAM_H #include "../../Common/MyCom.h" #include "../IStream.h" -class COffsetOutStream: - public IOutStream, - public CMyUnknownImp -{ - UInt64 _offset; +Z7_CLASS_IMP_NOQIB_1( + COffsetOutStream + , IOutStream +) + Z7_IFACE_COM7_IMP(ISequentialOutStream) + CMyComPtr<IOutStream> _stream; + UInt64 _offset; public: HRESULT Init(IOutStream *stream, UInt64 offset); - - MY_UNKNOWN_IMP - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - STDMETHOD(SetSize)(UInt64 newSize); }; #endif diff --git a/3rdparty/lzma/CPP/7zip/Common/OutBuffer.cpp b/3rdparty/lzma/CPP/7zip/Common/OutBuffer.cpp index 4ba34a053b1..197b3767efb 100644 --- a/3rdparty/lzma/CPP/7zip/Common/OutBuffer.cpp +++ b/3rdparty/lzma/CPP/7zip/Common/OutBuffer.cpp @@ -11,18 +11,18 @@ bool COutBuffer::Create(UInt32 bufSize) throw() const UInt32 kMinBlockSize = 1; if (bufSize < kMinBlockSize) bufSize = kMinBlockSize; - if (_buf != 0 && _bufSize == bufSize) + if (_buf && _bufSize == bufSize) return true; Free(); _bufSize = bufSize; _buf = (Byte *)::MidAlloc(bufSize); - return (_buf != 0); + return (_buf != NULL); } void COutBuffer::Free() throw() { ::MidFree(_buf); - _buf = 0; + _buf = NULL; } void COutBuffer::Init() throw() @@ -32,7 +32,7 @@ void COutBuffer::Init() throw() _pos = 0; _processedSize = 0; _overDict = false; - #ifdef _NO_EXCEPTIONS + #ifdef Z7_NO_EXCEPTIONS ErrorCode = S_OK; #endif } @@ -51,17 +51,17 @@ HRESULT COutBuffer::FlushPart() throw() // _streamPos < _bufSize UInt32 size = (_streamPos >= _pos) ? (_bufSize - _streamPos) : (_pos - _streamPos); HRESULT result = S_OK; - #ifdef _NO_EXCEPTIONS + #ifdef Z7_NO_EXCEPTIONS result = ErrorCode; #endif - if (_buf2 != 0) + if (_buf2) { memcpy(_buf2, _buf + _streamPos, size); _buf2 += size; } - if (_stream != 0 - #ifdef _NO_EXCEPTIONS + if (_stream + #ifdef Z7_NO_EXCEPTIONS && (ErrorCode == S_OK) #endif ) @@ -85,14 +85,14 @@ HRESULT COutBuffer::FlushPart() throw() HRESULT COutBuffer::Flush() throw() { - #ifdef _NO_EXCEPTIONS + #ifdef Z7_NO_EXCEPTIONS if (ErrorCode != S_OK) return ErrorCode; #endif while (_streamPos != _pos) { - HRESULT result = FlushPart(); + const HRESULT result = FlushPart(); if (result != S_OK) return result; } @@ -101,8 +101,8 @@ HRESULT COutBuffer::Flush() throw() void COutBuffer::FlushWithCheck() { - HRESULT result = Flush(); - #ifdef _NO_EXCEPTIONS + const HRESULT result = Flush(); + #ifdef Z7_NO_EXCEPTIONS ErrorCode = result; #else if (result != S_OK) diff --git a/3rdparty/lzma/CPP/7zip/Common/OutBuffer.h b/3rdparty/lzma/CPP/7zip/Common/OutBuffer.h index 3bdfb87c592..cef7d502dfe 100644 --- a/3rdparty/lzma/CPP/7zip/Common/OutBuffer.h +++ b/3rdparty/lzma/CPP/7zip/Common/OutBuffer.h @@ -1,13 +1,13 @@ // OutBuffer.h -#ifndef __OUT_BUFFER_H -#define __OUT_BUFFER_H +#ifndef ZIP7_INC_OUT_BUFFER_H +#define ZIP7_INC_OUT_BUFFER_H #include "../IStream.h" #include "../../Common/MyCom.h" #include "../../Common/MyException.h" -#ifndef _NO_EXCEPTIONS +#ifndef Z7_NO_EXCEPTIONS struct COutBufferException: public CSystemException { COutBufferException(HRESULT errorCode): CSystemException(errorCode) {} @@ -29,11 +29,11 @@ protected: HRESULT FlushPart() throw(); public: - #ifdef _NO_EXCEPTIONS + #ifdef Z7_NO_EXCEPTIONS HRESULT ErrorCode; #endif - COutBuffer(): _buf(0), _pos(0), _stream(0), _buf2(0) {} + COutBuffer(): _buf(NULL), _pos(0), _stream(NULL), _buf2(NULL) {} ~COutBuffer() { Free(); } bool Create(UInt32 bufSize) throw(); @@ -47,8 +47,11 @@ public: void WriteByte(Byte b) { - _buf[_pos++] = b; - if (_pos == _limitPos) + UInt32 pos = _pos; + _buf[pos] = b; + pos++; + _pos = pos; + if (pos == _limitPos) FlushWithCheck(); } void WriteBytes(const void *data, size_t size) diff --git a/3rdparty/lzma/CPP/7zip/Common/ProgressUtils.cpp b/3rdparty/lzma/CPP/7zip/Common/ProgressUtils.cpp index 41385ccb1cc..fb81f29b568 100644 --- a/3rdparty/lzma/CPP/7zip/Common/ProgressUtils.cpp +++ b/3rdparty/lzma/CPP/7zip/Common/ProgressUtils.cpp @@ -5,11 +5,11 @@ #include "ProgressUtils.h" CLocalProgress::CLocalProgress(): + SendRatio(true), + SendProgress(true), ProgressOffset(0), InSize(0), - OutSize(0), - SendRatio(true), - SendProgress(true) + OutSize(0) {} void CLocalProgress::Init(IProgress *progress, bool inSizeIsMain) @@ -20,7 +20,7 @@ void CLocalProgress::Init(IProgress *progress, bool inSizeIsMain) _inSizeIsMain = inSizeIsMain; } -STDMETHODIMP CLocalProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) +Z7_COM7F_IMF(CLocalProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)) { UInt64 inSize2 = InSize; UInt64 outSize2 = OutSize; @@ -32,7 +32,7 @@ STDMETHODIMP CLocalProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *ou if (SendRatio && _ratioProgress) { - RINOK(_ratioProgress->SetRatioInfo(&inSize2, &outSize2)); + RINOK(_ratioProgress->SetRatioInfo(&inSize2, &outSize2)) } if (SendProgress) diff --git a/3rdparty/lzma/CPP/7zip/Common/ProgressUtils.h b/3rdparty/lzma/CPP/7zip/Common/ProgressUtils.h index e94265ba715..dad5fccfa2c 100644 --- a/3rdparty/lzma/CPP/7zip/Common/ProgressUtils.h +++ b/3rdparty/lzma/CPP/7zip/Common/ProgressUtils.h @@ -1,35 +1,33 @@ // ProgressUtils.h -#ifndef __PROGRESS_UTILS_H -#define __PROGRESS_UTILS_H +#ifndef ZIP7_INC_PROGRESS_UTILS_H +#define ZIP7_INC_PROGRESS_UTILS_H #include "../../Common/MyCom.h" #include "../ICoder.h" #include "../IProgress.h" -class CLocalProgress: - public ICompressProgressInfo, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_1( + CLocalProgress + , ICompressProgressInfo +) +public: + bool SendRatio; + bool SendProgress; +private: + bool _inSizeIsMain; CMyComPtr<IProgress> _progress; CMyComPtr<ICompressProgressInfo> _ratioProgress; - bool _inSizeIsMain; public: UInt64 ProgressOffset; UInt64 InSize; UInt64 OutSize; - bool SendRatio; - bool SendProgress; CLocalProgress(); void Init(IProgress *progress, bool inSizeIsMain); HRESULT SetCur(); - - MY_UNKNOWN_IMP1(ICompressProgressInfo) - - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); }; #endif diff --git a/3rdparty/lzma/CPP/7zip/Common/PropId.cpp b/3rdparty/lzma/CPP/7zip/Common/PropId.cpp index 11d20d55753..6117b0e21b6 100644 --- a/3rdparty/lzma/CPP/7zip/Common/PropId.cpp +++ b/3rdparty/lzma/CPP/7zip/Common/PropId.cpp @@ -104,5 +104,14 @@ const Byte k7z_PROPID_To_VARTYPE[kpid_NUM_DEFINED] = VT_UI8, VT_BOOL, VT_BSTR, - VT_BSTR + VT_BSTR, + VT_BSTR, + VT_BOOL, + VT_FILETIME, // kpidChangeTime + VT_UI4, + VT_UI4, + VT_UI4, + VT_UI4, + VT_UI4, + VT_UI4 // kpidDevMinor }; diff --git a/3rdparty/lzma/CPP/7zip/Common/RegisterArc.h b/3rdparty/lzma/CPP/7zip/Common/RegisterArc.h index 3421ba1b164..55c1483f2e4 100644 --- a/3rdparty/lzma/CPP/7zip/Common/RegisterArc.h +++ b/3rdparty/lzma/CPP/7zip/Common/RegisterArc.h @@ -1,13 +1,13 @@ // RegisterArc.h -#ifndef __REGISTER_ARC_H -#define __REGISTER_ARC_H +#ifndef ZIP7_INC_REGISTER_ARC_H +#define ZIP7_INC_REGISTER_ARC_H #include "../Archive/IArchive.h" struct CArcInfo { - UInt16 Flags; + UInt32 Flags; Byte Id; Byte SignatureSize; UInt16 SignatureOffset; @@ -17,6 +17,8 @@ struct CArcInfo const char *Ext; const char *AddExt; + UInt32 TimeFlags; + Func_CreateInArchive CreateInArchive; Func_CreateOutArchive CreateOutArchive; Func_IsArc IsArc; @@ -32,29 +34,29 @@ void RegisterArc(const CArcInfo *arcInfo) throw(); #define IMP_CreateArcIn IMP_CreateArcIn_2(CHandler()) -#ifdef EXTRACT_ONLY +#ifdef Z7_EXTRACT_ONLY #define IMP_CreateArcOut #define CreateArcOut NULL #else #define IMP_CreateArcOut static IOutArchive *CreateArcOut() { return new CHandler(); } #endif -#define REGISTER_ARC_V(n, e, ae, id, sigSize, sig, offs, flags, crIn, crOut, isArc) \ - static const CArcInfo g_ArcInfo = { flags, id, sigSize, offs, sig, n, e, ae, crIn, crOut, isArc } ; \ +#define REGISTER_ARC_V(n, e, ae, id, sigSize, sig, offs, flags, tf, crIn, crOut, isArc) \ + static const CArcInfo g_ArcInfo = { flags, id, sigSize, offs, sig, n, e, ae, tf, crIn, crOut, isArc } ; \ -#define REGISTER_ARC_R(n, e, ae, id, sigSize, sig, offs, flags, crIn, crOut, isArc) \ - REGISTER_ARC_V(n, e, ae, id, sigSize, sig, offs, flags, crIn, crOut, isArc) \ +#define REGISTER_ARC_R(n, e, ae, id, sigSize, sig, offs, flags, tf, crIn, crOut, isArc) \ + REGISTER_ARC_V (n, e, ae, id, sigSize, sig, offs, flags, tf, crIn, crOut, isArc) \ struct CRegisterArc { CRegisterArc() { RegisterArc(&g_ArcInfo); }}; \ static CRegisterArc g_RegisterArc; #define REGISTER_ARC_I_CLS(cls, n, e, ae, id, sig, offs, flags, isArc) \ IMP_CreateArcIn_2(cls) \ - REGISTER_ARC_R(n, e, ae, id, ARRAY_SIZE(sig), sig, offs, flags, CreateArc, NULL, isArc) + REGISTER_ARC_R(n, e, ae, id, Z7_ARRAY_SIZE(sig), sig, offs, flags, 0, CreateArc, NULL, isArc) #define REGISTER_ARC_I_CLS_NO_SIG(cls, n, e, ae, id, offs, flags, isArc) \ IMP_CreateArcIn_2(cls) \ - REGISTER_ARC_R(n, e, ae, id, 0, NULL, offs, flags, CreateArc, NULL, isArc) + REGISTER_ARC_R(n, e, ae, id, 0, NULL, offs, flags, 0, CreateArc, NULL, isArc) #define REGISTER_ARC_I(n, e, ae, id, sig, offs, flags, isArc) \ REGISTER_ARC_I_CLS(CHandler(), n, e, ae, id, sig, offs, flags, isArc) @@ -63,15 +65,15 @@ void RegisterArc(const CArcInfo *arcInfo) throw(); REGISTER_ARC_I_CLS_NO_SIG(CHandler(), n, e, ae, id, offs, flags, isArc) -#define REGISTER_ARC_IO(n, e, ae, id, sig, offs, flags, isArc) \ +#define REGISTER_ARC_IO(n, e, ae, id, sig, offs, flags, tf, isArc) \ IMP_CreateArcIn \ IMP_CreateArcOut \ - REGISTER_ARC_R(n, e, ae, id, ARRAY_SIZE(sig), sig, offs, flags, CreateArc, CreateArcOut, isArc) + REGISTER_ARC_R(n, e, ae, id, Z7_ARRAY_SIZE(sig), sig, offs, flags, tf, CreateArc, CreateArcOut, isArc) -#define REGISTER_ARC_IO_DECREMENT_SIG(n, e, ae, id, sig, offs, flags, isArc) \ +#define REGISTER_ARC_IO_DECREMENT_SIG(n, e, ae, id, sig, offs, flags, tf, isArc) \ IMP_CreateArcIn \ IMP_CreateArcOut \ - REGISTER_ARC_V(n, e, ae, id, ARRAY_SIZE(sig), sig, offs, flags, CreateArc, CreateArcOut, isArc) \ + REGISTER_ARC_V(n, e, ae, id, Z7_ARRAY_SIZE(sig), sig, offs, flags, tf, CreateArc, CreateArcOut, isArc) \ struct CRegisterArcDecSig { CRegisterArcDecSig() { sig[0]--; RegisterArc(&g_ArcInfo); }}; \ static CRegisterArcDecSig g_RegisterArc; diff --git a/3rdparty/lzma/CPP/7zip/Common/RegisterCodec.h b/3rdparty/lzma/CPP/7zip/Common/RegisterCodec.h index 7ddb7604b9a..cf94998ac7d 100644 --- a/3rdparty/lzma/CPP/7zip/Common/RegisterCodec.h +++ b/3rdparty/lzma/CPP/7zip/Common/RegisterCodec.h @@ -1,7 +1,7 @@ // RegisterCodec.h -#ifndef __REGISTER_CODEC_H -#define __REGISTER_CODEC_H +#ifndef ZIP7_INC_REGISTER_CODEC_H +#define ZIP7_INC_REGISTER_CODEC_H #include "../Common/MethodId.h" @@ -26,29 +26,29 @@ void RegisterCodec(const CCodecInfo *codecInfo) throw(); #define REGISTER_CODEC_CREATE(name, cls) REGISTER_CODEC_CREATE_2(name, cls, ICompressCoder) #define REGISTER_CODEC_NAME(x) CRegisterCodec ## x -#define REGISTER_CODEC_VAR static const CCodecInfo g_CodecInfo = +#define REGISTER_CODEC_VAR(x) static const CCodecInfo g_CodecInfo_ ## x = #define REGISTER_CODEC(x) struct REGISTER_CODEC_NAME(x) { \ - REGISTER_CODEC_NAME(x)() { RegisterCodec(&g_CodecInfo); }}; \ - static REGISTER_CODEC_NAME(x) g_RegisterCodec; + REGISTER_CODEC_NAME(x)() { RegisterCodec(&g_CodecInfo_ ## x); }}; \ + static REGISTER_CODEC_NAME(x) g_RegisterCodec_ ## x; #define REGISTER_CODECS_NAME(x) CRegisterCodecs ## x #define REGISTER_CODECS_VAR static const CCodecInfo g_CodecsInfo[] = #define REGISTER_CODECS(x) struct REGISTER_CODECS_NAME(x) { \ - REGISTER_CODECS_NAME(x)() { for (unsigned i = 0; i < ARRAY_SIZE(g_CodecsInfo); i++) \ + REGISTER_CODECS_NAME(x)() { for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_CodecsInfo); i++) \ RegisterCodec(&g_CodecsInfo[i]); }}; \ static REGISTER_CODECS_NAME(x) g_RegisterCodecs; #define REGISTER_CODEC_2(x, crDec, crEnc, id, name) \ - REGISTER_CODEC_VAR \ + REGISTER_CODEC_VAR(x) \ { crDec, crEnc, id, name, 1, false }; \ REGISTER_CODEC(x) -#ifdef EXTRACT_ONLY +#ifdef Z7_EXTRACT_ONLY #define REGISTER_CODEC_E(x, clsDec, clsEnc, id, name) \ REGISTER_CODEC_CREATE(CreateDec, clsDec) \ REGISTER_CODEC_2(x, CreateDec, NULL, id, name) @@ -67,19 +67,19 @@ void RegisterCodec(const CCodecInfo *codecInfo) throw(); { crDec, crEnc, id, name, 1, true } #define REGISTER_FILTER(x, crDec, crEnc, id, name) \ - REGISTER_CODEC_VAR \ + REGISTER_CODEC_VAR(x) \ REGISTER_FILTER_ITEM(crDec, crEnc, id, name); \ REGISTER_CODEC(x) -#ifdef EXTRACT_ONLY +#ifdef Z7_EXTRACT_ONLY #define REGISTER_FILTER_E(x, clsDec, clsEnc, id, name) \ - REGISTER_FILTER_CREATE(CreateDec, clsDec) \ - REGISTER_FILTER(x, CreateDec, NULL, id, name) + REGISTER_FILTER_CREATE(x ## _CreateDec, clsDec) \ + REGISTER_FILTER(x, x ## _CreateDec, NULL, id, name) #else #define REGISTER_FILTER_E(x, clsDec, clsEnc, id, name) \ - REGISTER_FILTER_CREATE(CreateDec, clsDec) \ - REGISTER_FILTER_CREATE(CreateEnc, clsEnc) \ - REGISTER_FILTER(x, CreateDec, CreateEnc, id, name) + REGISTER_FILTER_CREATE(x ## _CreateDec, clsDec) \ + REGISTER_FILTER_CREATE(x ## _CreateEnc, clsEnc) \ + REGISTER_FILTER(x, x ## _CreateDec, x ## _CreateEnc, id, name) #endif @@ -97,7 +97,7 @@ void RegisterHasher(const CHasherInfo *hasher) throw(); #define REGISTER_HASHER_NAME(x) CRegHasher_ ## x #define REGISTER_HASHER(cls, id, name, size) \ - STDMETHODIMP_(UInt32) cls::GetDigestSize() throw() { return size; } \ + Z7_COM7F_IMF2(UInt32, cls::GetDigestSize()) { return size; } \ static IHasher *CreateHasherSpec() { return new cls(); } \ static const CHasherInfo g_HasherInfo = { CreateHasherSpec, id, name, size }; \ struct REGISTER_HASHER_NAME(cls) { REGISTER_HASHER_NAME(cls)() { RegisterHasher(&g_HasherInfo); }}; \ diff --git a/3rdparty/lzma/CPP/7zip/Common/StdAfx.h b/3rdparty/lzma/CPP/7zip/Common/StdAfx.h index 1cbd7feaeec..80866550d1f 100644 --- a/3rdparty/lzma/CPP/7zip/Common/StdAfx.h +++ b/3rdparty/lzma/CPP/7zip/Common/StdAfx.h @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../Common/Common.h" #endif diff --git a/3rdparty/lzma/CPP/7zip/Common/StreamBinder.cpp b/3rdparty/lzma/CPP/7zip/Common/StreamBinder.cpp index 435440c6649..38334af9638 100644 --- a/3rdparty/lzma/CPP/7zip/Common/StreamBinder.cpp +++ b/3rdparty/lzma/CPP/7zip/Common/StreamBinder.cpp @@ -6,50 +6,48 @@ #include "StreamBinder.h" -class CBinderInStream: - public ISequentialInStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_1( + CBinderInStream + , ISequentialInStream +) CStreamBinder *_binder; public: - MY_UNKNOWN_IMP1(ISequentialInStream) - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - ~CBinderInStream() { _binder->CloseRead(); } + ~CBinderInStream() { _binder->CloseRead_CallOnce(); } CBinderInStream(CStreamBinder *binder): _binder(binder) {} }; -STDMETHODIMP CBinderInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CBinderInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { return _binder->Read(data, size, processedSize); } -class CBinderOutStream: - public ISequentialOutStream, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_COM_1( + CBinderOutStream + , ISequentialOutStream +) CStreamBinder *_binder; public: - MY_UNKNOWN_IMP1(ISequentialOutStream) - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); ~CBinderOutStream() { _binder->CloseWrite(); } CBinderOutStream(CStreamBinder *binder): _binder(binder) {} }; -STDMETHODIMP CBinderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CBinderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { return _binder->Write(data, size, processedSize); } - -WRes CStreamBinder::CreateEvents() +static HRESULT Event_Create_or_Reset(NWindows::NSynchronization::CAutoResetEvent &event) { - RINOK(_canWrite_Event.Create()); - RINOK(_canRead_Event.Create()); - return _readingWasClosed_Event.Create(); + const WRes wres = event.CreateIfNotCreated_Reset(); + return HRESULT_FROM_WIN32(wres); } -void CStreamBinder::ReInit() +HRESULT CStreamBinder::Create_ReInit() { - _canWrite_Event.Reset(); - _canRead_Event.Reset(); - _readingWasClosed_Event.Reset(); + RINOK(Event_Create_or_Reset(_canRead_Event)) + // RINOK(Event_Create_or_Reset(_canWrite_Event)) + + // _canWrite_Semaphore.Close(); + // we need at least 3 items of maxCount: 1 for normal unlock in Read(), 2 items for unlock in CloseRead_CallOnce() + _canWrite_Semaphore.OptCreateInit(0, 3); // _readingWasClosed = false; _readingWasClosed2 = false; @@ -59,27 +57,14 @@ void CStreamBinder::ReInit() _buf = NULL; ProcessedSize = 0; // WritingWasCut = false; + return S_OK; } -void CStreamBinder::CreateStreams(ISequentialInStream **inStream, ISequentialOutStream **outStream) +void CStreamBinder::CreateStreams2(CMyComPtr<ISequentialInStream> &inStream, CMyComPtr<ISequentialOutStream> &outStream) { - // _readingWasClosed = false; - _readingWasClosed2 = false; - - _waitWrite = true; - _bufSize = 0; - _buf = NULL; - ProcessedSize = 0; - // WritingWasCut = false; - - CBinderInStream *inStreamSpec = new CBinderInStream(this); - CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec); - *inStream = inStreamLoc.Detach(); - - CBinderOutStream *outStreamSpec = new CBinderOutStream(this); - CMyComPtr<ISequentialOutStream> outStreamLoc(outStreamSpec); - *outStream = outStreamLoc.Detach(); + inStream = new CBinderInStream(this); + outStream = new CBinderOutStream(this); } // (_canRead_Event && _bufSize == 0) means that stream is finished. @@ -92,7 +77,9 @@ HRESULT CStreamBinder::Read(void *data, UInt32 size, UInt32 *processedSize) { if (_waitWrite) { - RINOK(_canRead_Event.Lock()); + WRes wres = _canRead_Event.Lock(); + if (wres != 0) + return HRESULT_FROM_WIN32(wres); _waitWrite = false; } if (size > _bufSize) @@ -105,17 +92,25 @@ HRESULT CStreamBinder::Read(void *data, UInt32 size, UInt32 *processedSize) if (processedSize) *processedSize = size; _bufSize -= size; + + /* + if (_bufSize == 0), then we have read whole buffer + we have two ways here: + - if we check (_bufSize == 0) here, we unlock Write only after full data Reading - it reduces the number of syncs + - if we don't check (_bufSize == 0) here, we unlock Write after partial data Reading + */ if (_bufSize == 0) { _waitWrite = true; - _canRead_Event.Reset(); - _canWrite_Event.Set(); + // _canWrite_Event.Set(); + _canWrite_Semaphore.Release(); } } } return S_OK; } + HRESULT CStreamBinder::Write(const void *data, UInt32 size, UInt32 *processedSize) { if (processedSize) @@ -135,20 +130,20 @@ HRESULT CStreamBinder::Write(const void *data, UInt32 size, UInt32 *processedSiz _readingWasClosed2 = true; */ - HANDLE events[2] = { _canWrite_Event, _readingWasClosed_Event }; - DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE); - if (waitResult >= WAIT_OBJECT_0 + 2) - return E_FAIL; + _canWrite_Semaphore.Lock(); + // _bufSize : is remain size that was not read size -= _bufSize; + + // size : is size of data that was read if (size != 0) { + // if some data was read, then we report that size and return if (processedSize) *processedSize = size; return S_OK; } - // if (waitResult == WAIT_OBJECT_0 + 1) - _readingWasClosed2 = true; + _readingWasClosed2 = true; } // WritingWasCut = true; diff --git a/3rdparty/lzma/CPP/7zip/Common/StreamBinder.h b/3rdparty/lzma/CPP/7zip/Common/StreamBinder.h index 12088a94586..c0a70793c4b 100644 --- a/3rdparty/lzma/CPP/7zip/Common/StreamBinder.h +++ b/3rdparty/lzma/CPP/7zip/Common/StreamBinder.h @@ -1,52 +1,70 @@ // StreamBinder.h -#ifndef __STREAM_BINDER_H -#define __STREAM_BINDER_H +#ifndef ZIP7_INC_STREAM_BINDER_H +#define ZIP7_INC_STREAM_BINDER_H #include "../../Windows/Synchronization.h" #include "../IStream.h" /* -We don't use probably UNSAFE version: -reader thread: +We can use one from two code versions here: with Event or with Semaphore to unlock Writer thread +The difference for cases where Reading must be closed before Writing closing + +1) Event Version: _canWrite_Event + We call _canWrite_Event.Set() without waiting _canRead_Event in CloseRead() function. + The writer thread can get (_readingWasClosed) status in one from two iterations. + It's ambiguity of processing flow. But probably it's SAFE to use, if Event functions provide memory barriers. + reader thread: _canWrite_Event.Set(); - _readingWasClosed = true + _readingWasClosed = true; _canWrite_Event.Set(); -writer thread: + writer thread: _canWrite_Event.Wait() if (_readingWasClosed) -Can second call of _canWrite_Event.Set() be executed without memory barrier, if event is already set? + +2) Semaphore Version: _canWrite_Semaphore + writer thread always will detect closing of reading in latest iteration after all data processing iterations */ class CStreamBinder { - NWindows::NSynchronization::CAutoResetEvent _canWrite_Event; - NWindows::NSynchronization::CManualResetEvent _canRead_Event; - NWindows::NSynchronization::CManualResetEvent _readingWasClosed_Event; + NWindows::NSynchronization::CAutoResetEvent _canRead_Event; + // NWindows::NSynchronization::CAutoResetEvent _canWrite_Event; + NWindows::NSynchronization::CSemaphore _canWrite_Semaphore; - // bool _readingWasClosed; - bool _readingWasClosed2; + // bool _readingWasClosed; // set it in reader thread and check it in write thread + bool _readingWasClosed2; // use it in writer thread // bool WritingWasCut; - bool _waitWrite; + bool _waitWrite; // use it in reader thread UInt32 _bufSize; const void *_buf; public: - UInt64 ProcessedSize; + UInt64 ProcessedSize; // the size that was read by reader thread - WRes CreateEvents(); - void CreateStreams(ISequentialInStream **inStream, ISequentialOutStream **outStream); + void CreateStreams2(CMyComPtr<ISequentialInStream> &inStream, CMyComPtr<ISequentialOutStream> &outStream); - void ReInit(); + HRESULT Create_ReInit(); HRESULT Read(void *data, UInt32 size, UInt32 *processedSize); HRESULT Write(const void *data, UInt32 size, UInt32 *processedSize); - void CloseRead() + void CloseRead_CallOnce() { - _readingWasClosed_Event.Set(); - // _readingWasClosed = true; - // _canWrite_Event.Set(); + // call it only once: for example, in destructor + + /* + _readingWasClosed = true; + _canWrite_Event.Set(); + */ + + /* + We must relase Semaphore only once !!! + we must release at least 2 items of Semaphore: + one item to unlock partial Write(), if Read() have read some items + then additional item to stop writing (_bufSize will be 0) + */ + _canWrite_Semaphore.Release(2); } void CloseWrite() diff --git a/3rdparty/lzma/CPP/7zip/Common/StreamObjects.cpp b/3rdparty/lzma/CPP/7zip/Common/StreamObjects.cpp index 8136716d66f..b54f4237359 100644 --- a/3rdparty/lzma/CPP/7zip/Common/StreamObjects.cpp +++ b/3rdparty/lzma/CPP/7zip/Common/StreamObjects.cpp @@ -2,13 +2,11 @@ #include "StdAfx.h" -#include <stdlib.h> - #include "../../../C/Alloc.h" #include "StreamObjects.h" -STDMETHODIMP CBufferInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CBufferInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -26,7 +24,7 @@ STDMETHODIMP CBufferInStream::Read(void *data, UInt32 size, UInt32 *processedSiz return S_OK; } -STDMETHODIMP CBufferInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(CBufferInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { switch (seekOrigin) { @@ -37,13 +35,13 @@ STDMETHODIMP CBufferInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newP } if (offset < 0) return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - _pos = offset; + _pos = (UInt64)offset; if (newPosition) - *newPosition = offset; + *newPosition = (UInt64)offset; return S_OK; } -STDMETHODIMP CBufInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CBufInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -61,7 +59,7 @@ STDMETHODIMP CBufInStream::Read(void *data, UInt32 size, UInt32 *processedSize) return S_OK; } -STDMETHODIMP CBufInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(CBufInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { switch (seekOrigin) { @@ -72,9 +70,9 @@ STDMETHODIMP CBufInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosi } if (offset < 0) return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - _pos = offset; + _pos = (UInt64)offset; if (newPosition) - *newPosition = offset; + *newPosition = (UInt64)offset; return S_OK; } @@ -99,8 +97,8 @@ void Create_BufInStream_WithNewBuffer(const void *data, size_t size, ISequential void CByteDynBuffer::Free() throw() { - free(_buf); - _buf = 0; + MyFree(_buf); + _buf = NULL; _capacity = 0; } @@ -108,15 +106,10 @@ bool CByteDynBuffer::EnsureCapacity(size_t cap) throw() { if (cap <= _capacity) return true; - size_t delta; - if (_capacity > 64) - delta = _capacity / 4; - else if (_capacity > 8) - delta = 16; - else - delta = 4; - cap = MyMax(_capacity + delta, cap); - Byte *buf = (Byte *)realloc(_buf, cap); + const size_t cap2 = _capacity + _capacity / 4; + if (cap < cap2) + cap = cap2; + Byte *buf = (Byte *)MyRealloc(_buf, cap); if (!buf) return false; _buf = buf; @@ -139,7 +132,7 @@ void CDynBufSeqOutStream::CopyToBuffer(CByteBuffer &dest) const dest.CopyFrom((const Byte *)_buffer, _size); } -STDMETHODIMP CDynBufSeqOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CDynBufSeqOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -155,7 +148,7 @@ STDMETHODIMP CDynBufSeqOutStream::Write(const void *data, UInt32 size, UInt32 *p return S_OK; } -STDMETHODIMP CBufPtrSeqOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CBufPtrSeqOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { size_t rem = _size - _pos; if (rem > size) @@ -170,7 +163,7 @@ STDMETHODIMP CBufPtrSeqOutStream::Write(const void *data, UInt32 size, UInt32 *p return (rem != 0 || size == 0) ? S_OK : E_FAIL; } -STDMETHODIMP CSequentialOutStreamSizeCount::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CSequentialOutStreamSizeCount::Write(const void *data, UInt32 size, UInt32 *processedSize)) { UInt32 realProcessedSize; HRESULT result = _stream->Write(data, size, &realProcessedSize); @@ -185,9 +178,9 @@ static const UInt64 kEmptyTag = (UInt64)(Int64)-1; void CCachedInStream::Free() throw() { MyFree(_tags); - _tags = 0; + _tags = NULL; MidFree(_data); - _data = 0; + _data = NULL; } bool CCachedInStream::Alloc(unsigned blockSizeLog, unsigned numBlocksLog) throw() @@ -196,19 +189,19 @@ bool CCachedInStream::Alloc(unsigned blockSizeLog, unsigned numBlocksLog) throw( if (sizeLog >= sizeof(size_t) * 8) return false; size_t dataSize = (size_t)1 << sizeLog; - if (_data == 0 || dataSize != _dataSize) + if (!_data || dataSize != _dataSize) { MidFree(_data); _data = (Byte *)MidAlloc(dataSize); - if (_data == 0) + if (!_data) return false; _dataSize = dataSize; } - if (_tags == 0 || numBlocksLog != _numBlocksLog) + if (!_tags || numBlocksLog != _numBlocksLog) { MyFree(_tags); _tags = (UInt64 *)MyAlloc(sizeof(UInt64) << numBlocksLog); - if (_tags == 0) + if (!_tags) return false; _numBlocksLog = numBlocksLog; } @@ -220,12 +213,12 @@ void CCachedInStream::Init(UInt64 size) throw() { _size = size; _pos = 0; - size_t numBlocks = (size_t)1 << _numBlocksLog; + const size_t numBlocks = (size_t)1 << _numBlocksLog; for (size_t i = 0; i < numBlocks; i++) _tags[i] = kEmptyTag; } -STDMETHODIMP CCachedInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CCachedInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -235,28 +228,39 @@ STDMETHODIMP CCachedInStream::Read(void *data, UInt32 size, UInt32 *processedSiz return S_OK; { - UInt64 rem = _size - _pos; + const UInt64 rem = _size - _pos; if (size > rem) size = (UInt32)rem; } while (size != 0) { - UInt64 cacheTag = _pos >> _blockSizeLog; - size_t cacheIndex = (size_t)cacheTag & (((size_t)1 << _numBlocksLog) - 1); + const UInt64 cacheTag = _pos >> _blockSizeLog; + const size_t cacheIndex = (size_t)cacheTag & (((size_t)1 << _numBlocksLog) - 1); Byte *p = _data + (cacheIndex << _blockSizeLog); + if (_tags[cacheIndex] != cacheTag) { - UInt64 remInBlock = _size - (cacheTag << _blockSizeLog); + _tags[cacheIndex] = kEmptyTag; + const UInt64 remInBlock = _size - (cacheTag << _blockSizeLog); size_t blockSize = (size_t)1 << _blockSizeLog; if (blockSize > remInBlock) blockSize = (size_t)remInBlock; - RINOK(ReadBlock(cacheTag, p, blockSize)); + + RINOK(ReadBlock(cacheTag, p, blockSize)) + _tags[cacheIndex] = cacheTag; } - size_t offset = (size_t)_pos & (((size_t)1 << _blockSizeLog) - 1); - UInt32 cur = (UInt32)MyMin(((size_t)1 << _blockSizeLog) - offset, (size_t)size); + + const size_t kBlockSize = (size_t)1 << _blockSizeLog; + const size_t offset = (size_t)_pos & (kBlockSize - 1); + UInt32 cur = size; + const size_t rem = kBlockSize - offset; + if (cur > rem) + cur = (UInt32)rem; + memcpy(data, p + offset, cur); + if (processedSize) *processedSize += cur; data = (void *)((const Byte *)data + cur); @@ -266,8 +270,9 @@ STDMETHODIMP CCachedInStream::Read(void *data, UInt32 size, UInt32 *processedSiz return S_OK; } + -STDMETHODIMP CCachedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +Z7_COM7F_IMF(CCachedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) { switch (seekOrigin) { @@ -278,8 +283,8 @@ STDMETHODIMP CCachedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newP } if (offset < 0) return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - _pos = offset; + _pos = (UInt64)offset; if (newPosition) - *newPosition = offset; + *newPosition = (UInt64)offset; return S_OK; } diff --git a/3rdparty/lzma/CPP/7zip/Common/StreamObjects.h b/3rdparty/lzma/CPP/7zip/Common/StreamObjects.h index e20e9bd80de..2c0ebea9d62 100644 --- a/3rdparty/lzma/CPP/7zip/Common/StreamObjects.h +++ b/3rdparty/lzma/CPP/7zip/Common/StreamObjects.h @@ -1,7 +1,7 @@ // StreamObjects.h -#ifndef __STREAM_OBJECTS_H -#define __STREAM_OBJECTS_H +#ifndef ZIP7_INC_STREAM_OBJECTS_H +#define ZIP7_INC_STREAM_OBJECTS_H #include "../../Common/MyBuffer.h" #include "../../Common/MyCom.h" @@ -9,39 +9,33 @@ #include "../IStream.h" -class CBufferInStream: - public IInStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_IInStream( + CBufferInStream +) UInt64 _pos; public: CByteBuffer Buf; void Init() { _pos = 0; } - - MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); }; -struct CReferenceBuf: - public IUnknown, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_COM_0( + CReferenceBuf +) +public: CByteBuffer Buf; - MY_UNKNOWN_IMP }; -class CBufInStream: - public IInStream, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_IInStream( + CBufInStream +) const Byte *_data; UInt64 _pos; size_t _size; CMyComPtr<IUnknown> _ref; public: - void Init(const Byte *data, size_t size, IUnknown *ref = 0) + void Init(const Byte *data, size_t size, IUnknown *ref = NULL) { _data = data; _size = size; @@ -50,22 +44,24 @@ public: } void Init(CReferenceBuf *ref) { Init(ref->Buf, ref->Buf.Size(), ref); } - MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); + // Seek() is allowed here. So reading order could be changed + bool WasFinished() const { return _pos == _size; } }; + void Create_BufInStream_WithReference(const void *data, size_t size, IUnknown *ref, ISequentialInStream **stream); void Create_BufInStream_WithNewBuffer(const void *data, size_t size, ISequentialInStream **stream); inline void Create_BufInStream_WithNewBuffer(const CByteBuffer &buf, ISequentialInStream **stream) { Create_BufInStream_WithNewBuffer(buf, buf.Size(), stream); } -class CByteDynBuffer + +class CByteDynBuffer Z7_final { size_t _capacity; Byte *_buf; + Z7_CLASS_NO_COPY(CByteDynBuffer) public: - CByteDynBuffer(): _capacity(0), _buf(0) {}; + CByteDynBuffer(): _capacity(0), _buf(NULL) {} // there is no copy constructor. So don't copy this object. ~CByteDynBuffer() { Free(); } void Free() throw(); @@ -75,10 +71,11 @@ public: bool EnsureCapacity(size_t capacity) throw(); }; -class CDynBufSeqOutStream: - public ISequentialOutStream, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_COM_1( + CDynBufSeqOutStream + , ISequentialOutStream +) CByteDynBuffer _buffer; size_t _size; public: @@ -89,15 +86,13 @@ public: void CopyToBuffer(CByteBuffer &dest) const; Byte *GetBufPtrForWriting(size_t addSize); void UpdateSize(size_t addSize) { _size += addSize; } - - MY_UNKNOWN_IMP1(ISequentialOutStream) - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); }; -class CBufPtrSeqOutStream: - public ISequentialOutStream, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_COM_1( + CBufPtrSeqOutStream + , ISequentialOutStream +) Byte *_buffer; size_t _size; size_t _pos; @@ -109,30 +104,28 @@ public: _size = size; } size_t GetPos() const { return _pos; } - - MY_UNKNOWN_IMP1(ISequentialOutStream) - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); }; -class CSequentialOutStreamSizeCount: - public ISequentialOutStream, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_COM_1( + CSequentialOutStreamSizeCount + , ISequentialOutStream +) CMyComPtr<ISequentialOutStream> _stream; UInt64 _size; public: void SetStream(ISequentialOutStream *stream) { _stream = stream; } void Init() { _size = 0; } UInt64 GetSize() const { return _size; } - - MY_UNKNOWN_IMP1(ISequentialOutStream) - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); }; + class CCachedInStream: public IInStream, public CMyUnknownImp { + Z7_IFACES_IMP_UNK_2(ISequentialInStream, IInStream) + UInt64 *_tags; Byte *_data; size_t _dataSize; @@ -143,15 +136,11 @@ class CCachedInStream: protected: virtual HRESULT ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize) = 0; public: - CCachedInStream(): _tags(0), _data(0) {} - virtual ~CCachedInStream() { Free(); } // the destructor must be virtual (release calls it) !!! + CCachedInStream(): _tags(NULL), _data(NULL) {} + virtual ~CCachedInStream() { Free(); } // the destructor must be virtual (Release() calls it) !!! void Free() throw(); bool Alloc(unsigned blockSizeLog, unsigned numBlocksLog) throw(); void Init(UInt64 size) throw(); - - MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); }; #endif diff --git a/3rdparty/lzma/CPP/7zip/Common/StreamUtils.cpp b/3rdparty/lzma/CPP/7zip/Common/StreamUtils.cpp index 1402f420599..24eed36c5bf 100644 --- a/3rdparty/lzma/CPP/7zip/Common/StreamUtils.cpp +++ b/3rdparty/lzma/CPP/7zip/Common/StreamUtils.cpp @@ -2,10 +2,55 @@ #include "StdAfx.h" +#include "../../Common/MyCom.h" + #include "StreamUtils.h" static const UInt32 kBlockSize = ((UInt32)1 << 31); + +HRESULT InStream_SeekToBegin(IInStream *stream) throw() +{ + return InStream_SeekSet(stream, 0); +} + + +HRESULT InStream_AtBegin_GetSize(IInStream *stream, UInt64 &sizeRes) throw() +{ +#ifdef _WIN32 + { + Z7_DECL_CMyComPtr_QI_FROM( + IStreamGetSize, + streamGetSize, stream) + if (streamGetSize && streamGetSize->GetSize(&sizeRes) == S_OK) + return S_OK; + } +#endif + const HRESULT hres = InStream_GetSize_SeekToEnd(stream, sizeRes); + const HRESULT hres2 = InStream_SeekToBegin(stream); + return hres != S_OK ? hres : hres2; +} + + +HRESULT InStream_GetPos_GetSize(IInStream *stream, UInt64 &curPosRes, UInt64 &sizeRes) throw() +{ + RINOK(InStream_GetPos(stream, curPosRes)) +#ifdef _WIN32 + { + Z7_DECL_CMyComPtr_QI_FROM( + IStreamGetSize, + streamGetSize, stream) + if (streamGetSize && streamGetSize->GetSize(&sizeRes) == S_OK) + return S_OK; + } +#endif + const HRESULT hres = InStream_GetSize_SeekToEnd(stream, sizeRes); + const HRESULT hres2 = InStream_SeekSet(stream, curPosRes); + return hres != S_OK ? hres : hres2; +} + + + HRESULT ReadStream(ISequentialInStream *stream, void *data, size_t *processedSize) throw() { size_t size = *processedSize; @@ -18,7 +63,7 @@ HRESULT ReadStream(ISequentialInStream *stream, void *data, size_t *processedSiz *processedSize += processedSizeLoc; data = (void *)((Byte *)data + processedSizeLoc); size -= processedSizeLoc; - RINOK(res); + RINOK(res) if (processedSizeLoc == 0) return S_OK; } @@ -28,14 +73,14 @@ HRESULT ReadStream(ISequentialInStream *stream, void *data, size_t *processedSiz HRESULT ReadStream_FALSE(ISequentialInStream *stream, void *data, size_t size) throw() { size_t processedSize = size; - RINOK(ReadStream(stream, data, &processedSize)); + RINOK(ReadStream(stream, data, &processedSize)) return (size == processedSize) ? S_OK : S_FALSE; } HRESULT ReadStream_FAIL(ISequentialInStream *stream, void *data, size_t size) throw() { size_t processedSize = size; - RINOK(ReadStream(stream, data, &processedSize)); + RINOK(ReadStream(stream, data, &processedSize)) return (size == processedSize) ? S_OK : E_FAIL; } @@ -48,7 +93,7 @@ HRESULT WriteStream(ISequentialOutStream *stream, const void *data, size_t size) HRESULT res = stream->Write(data, curSize, &processedSizeLoc); data = (const void *)((const Byte *)data + processedSizeLoc); size -= processedSizeLoc; - RINOK(res); + RINOK(res) if (processedSizeLoc == 0) return E_FAIL; } diff --git a/3rdparty/lzma/CPP/7zip/Common/StreamUtils.h b/3rdparty/lzma/CPP/7zip/Common/StreamUtils.h index ae914c004b0..35a62ed3e95 100644 --- a/3rdparty/lzma/CPP/7zip/Common/StreamUtils.h +++ b/3rdparty/lzma/CPP/7zip/Common/StreamUtils.h @@ -1,10 +1,28 @@ // StreamUtils.h -#ifndef __STREAM_UTILS_H -#define __STREAM_UTILS_H +#ifndef ZIP7_INC_STREAM_UTILS_H +#define ZIP7_INC_STREAM_UTILS_H #include "../IStream.h" +inline HRESULT InStream_SeekSet(IInStream *stream, UInt64 offset) throw() + { return stream->Seek((Int64)offset, STREAM_SEEK_SET, NULL); } +inline HRESULT InStream_GetPos(IInStream *stream, UInt64 &curPosRes) throw() + { return stream->Seek(0, STREAM_SEEK_CUR, &curPosRes); } +inline HRESULT InStream_GetSize_SeekToEnd(IInStream *stream, UInt64 &sizeRes) throw() + { return stream->Seek(0, STREAM_SEEK_END, &sizeRes); } + +HRESULT InStream_SeekToBegin(IInStream *stream) throw(); +HRESULT InStream_AtBegin_GetSize(IInStream *stream, UInt64 &size) throw(); +HRESULT InStream_GetPos_GetSize(IInStream *stream, UInt64 &curPosRes, UInt64 &sizeRes) throw(); + +inline HRESULT InStream_GetSize_SeekToBegin(IInStream *stream, UInt64 &sizeRes) throw() +{ + RINOK(InStream_SeekToBegin(stream)) + return InStream_AtBegin_GetSize(stream, sizeRes); +} + + HRESULT ReadStream(ISequentialInStream *stream, void *data, size_t *size) throw(); HRESULT ReadStream_FALSE(ISequentialInStream *stream, void *data, size_t size) throw(); HRESULT ReadStream_FAIL(ISequentialInStream *stream, void *data, size_t size) throw(); diff --git a/3rdparty/lzma/CPP/7zip/Common/UniqBlocks.cpp b/3rdparty/lzma/CPP/7zip/Common/UniqBlocks.cpp index 8f754e177e8..32dc27626ed 100644 --- a/3rdparty/lzma/CPP/7zip/Common/UniqBlocks.cpp +++ b/3rdparty/lzma/CPP/7zip/Common/UniqBlocks.cpp @@ -11,10 +11,10 @@ unsigned CUniqBlocks::AddUniq(const Byte *data, size_t size) unsigned left = 0, right = Sorted.Size(); while (left != right) { - unsigned mid = (left + right) / 2; - unsigned index = Sorted[mid]; + const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); + const unsigned index = Sorted[mid]; const CByteBuffer &buf = Bufs[index]; - size_t sizeMid = buf.Size(); + const size_t sizeMid = buf.Size(); if (size < sizeMid) right = mid; else if (size > sizeMid) @@ -23,7 +23,7 @@ unsigned CUniqBlocks::AddUniq(const Byte *data, size_t size) { if (size == 0) return index; - int cmp = memcmp(data, buf, size); + const int cmp = memcmp(data, buf, size); if (cmp == 0) return index; if (cmp < 0) diff --git a/3rdparty/lzma/CPP/7zip/Common/UniqBlocks.h b/3rdparty/lzma/CPP/7zip/Common/UniqBlocks.h index a376024e3df..66c7fa21b8a 100644 --- a/3rdparty/lzma/CPP/7zip/Common/UniqBlocks.h +++ b/3rdparty/lzma/CPP/7zip/Common/UniqBlocks.h @@ -1,11 +1,26 @@ // UniqBlocks.h -#ifndef __UNIQ_BLOCKS_H -#define __UNIQ_BLOCKS_H +#ifndef ZIP7_INC_UNIQ_BLOCKS_H +#define ZIP7_INC_UNIQ_BLOCKS_H -#include "../../Common/MyTypes.h" #include "../../Common/MyBuffer.h" -#include "../../Common/MyVector.h" +#include "../../Common/MyString.h" + +struct C_UInt32_UString_Map +{ + CRecordVector<UInt32> Numbers; + UStringVector Strings; + + void Add_UInt32(const UInt32 n) + { + Numbers.AddToUniqueSorted(n); + } + int Find(const UInt32 n) + { + return Numbers.FindInSorted(n); + } +}; + struct CUniqBlocks { @@ -19,7 +34,7 @@ struct CUniqBlocks bool IsOnlyEmpty() const { - return (Bufs.Size() == 0 || Bufs.Size() == 1 && Bufs[0].Size() == 0); + return (Bufs.Size() == 0 || (Bufs.Size() == 1 && Bufs[0].Size() == 0)); } }; diff --git a/3rdparty/lzma/CPP/7zip/Common/VirtThread.cpp b/3rdparty/lzma/CPP/7zip/Common/VirtThread.cpp index 77e3c1acfd8..3cf7296c26a 100644 --- a/3rdparty/lzma/CPP/7zip/Common/VirtThread.cpp +++ b/3rdparty/lzma/CPP/7zip/Common/VirtThread.cpp @@ -11,7 +11,7 @@ static THREAD_FUNC_DECL CoderThread(void *p) CVirtThread *t = (CVirtThread *)p; t->StartEvent.Lock(); if (t->Exit) - return 0; + return THREAD_FUNC_RET_ZERO; t->Execute(); t->FinishedEvent.Set(); } @@ -19,20 +19,20 @@ static THREAD_FUNC_DECL CoderThread(void *p) WRes CVirtThread::Create() { - RINOK(StartEvent.CreateIfNotCreated()); - RINOK(FinishedEvent.CreateIfNotCreated()); - StartEvent.Reset(); - FinishedEvent.Reset(); + RINOK_WRes(StartEvent.CreateIfNotCreated_Reset()) + RINOK_WRes(FinishedEvent.CreateIfNotCreated_Reset()) + // StartEvent.Reset(); + // FinishedEvent.Reset(); Exit = false; if (Thread.IsCreated()) return S_OK; return Thread.Create(CoderThread, this); } -void CVirtThread::Start() +WRes CVirtThread::Start() { Exit = false; - StartEvent.Set(); + return StartEvent.Set(); } void CVirtThread::WaitThreadFinish() @@ -42,7 +42,6 @@ void CVirtThread::WaitThreadFinish() StartEvent.Set(); if (Thread.IsCreated()) { - Thread.Wait(); - Thread.Close(); + Thread.Wait_Close(); } } diff --git a/3rdparty/lzma/CPP/7zip/Common/VirtThread.h b/3rdparty/lzma/CPP/7zip/Common/VirtThread.h index ebee158ca5b..809b3568985 100644 --- a/3rdparty/lzma/CPP/7zip/Common/VirtThread.h +++ b/3rdparty/lzma/CPP/7zip/Common/VirtThread.h @@ -1,7 +1,7 @@ // VirtThread.h -#ifndef __VIRT_THREAD_H -#define __VIRT_THREAD_H +#ifndef ZIP7_INC_VIRT_THREAD_H +#define ZIP7_INC_VIRT_THREAD_H #include "../../Windows/Synchronization.h" #include "../../Windows/Thread.h" @@ -13,12 +13,12 @@ struct CVirtThread NWindows::CThread Thread; bool Exit; - ~CVirtThread() { WaitThreadFinish(); } + virtual ~CVirtThread() { WaitThreadFinish(); } void WaitThreadFinish(); // call it in destructor of child class ! WRes Create(); - void Start(); + WRes Start(); virtual void Execute() = 0; - void WaitExecuteFinish() { FinishedEvent.Lock(); } + WRes WaitExecuteFinish() { return FinishedEvent.Lock(); } }; #endif diff --git a/3rdparty/lzma/CPP/7zip/Compress/Bcj2Coder.cpp b/3rdparty/lzma/CPP/7zip/Compress/Bcj2Coder.cpp index 96150c5f8b2..27e78b00b92 100644 --- a/3rdparty/lzma/CPP/7zip/Compress/Bcj2Coder.cpp +++ b/3rdparty/lzma/CPP/7zip/Compress/Bcj2Coder.cpp @@ -2,6 +2,8 @@ #include "StdAfx.h" +// #include <stdio.h> + #include "../../../C/Alloc.h" #include "../Common/StreamUtils.h" @@ -13,42 +15,47 @@ namespace NBcj2 { CBaseCoder::CBaseCoder() { - for (int i = 0; i < BCJ2_NUM_STREAMS + 1; i++) + for (unsigned i = 0; i < BCJ2_NUM_STREAMS + 1; i++) { _bufs[i] = NULL; - _bufsCurSizes[i] = 0; - _bufsNewSizes[i] = (1 << 18); + _bufsSizes[i] = 0; + _bufsSizes_New[i] = (1 << 18); } } CBaseCoder::~CBaseCoder() { - for (int i = 0; i < BCJ2_NUM_STREAMS + 1; i++) + for (unsigned i = 0; i < BCJ2_NUM_STREAMS + 1; i++) ::MidFree(_bufs[i]); } HRESULT CBaseCoder::Alloc(bool allocForOrig) { - unsigned num = allocForOrig ? BCJ2_NUM_STREAMS + 1 : BCJ2_NUM_STREAMS; + const unsigned num = allocForOrig ? BCJ2_NUM_STREAMS + 1 : BCJ2_NUM_STREAMS; for (unsigned i = 0; i < num; i++) { - UInt32 newSize = _bufsNewSizes[i]; - const UInt32 kMinBufSize = 1; - if (newSize < kMinBufSize) - newSize = kMinBufSize; - if (!_bufs[i] || newSize != _bufsCurSizes[i]) + UInt32 size = _bufsSizes_New[i]; + /* buffer sizes for BCJ2_STREAM_CALL and BCJ2_STREAM_JUMP streams + must be aligned for 4 */ + size &= ~(UInt32)3; + const UInt32 kMinBufSize = 4; + if (size < kMinBufSize) + size = kMinBufSize; + // size = 4 * 100; // for debug + // if (BCJ2_IS_32BIT_STREAM(i) == 1) size = 4 * 1; // for debug + if (!_bufs[i] || size != _bufsSizes[i]) { if (_bufs[i]) { ::MidFree(_bufs[i]); - _bufs[i] = 0; + _bufs[i] = NULL; } - _bufsCurSizes[i] = 0; - Byte *buf = (Byte *)::MidAlloc(newSize); - _bufs[i] = buf; + _bufsSizes[i] = 0; + Byte *buf = (Byte *)::MidAlloc(size); if (!buf) return E_OUTOFMEMORY; - _bufsCurSizes[i] = newSize; + _bufs[i] = buf; + _bufsSizes[i] = size; } } return S_OK; @@ -56,23 +63,30 @@ HRESULT CBaseCoder::Alloc(bool allocForOrig) -#ifndef EXTRACT_ONLY +#ifndef Z7_EXTRACT_ONLY -CEncoder::CEncoder(): _relatLim(BCJ2_RELAT_LIMIT) {} +CEncoder::CEncoder(): + _relatLim(BCJ2_ENC_RELAT_LIMIT_DEFAULT) + // , _excludeRangeBits(BCJ2_RELAT_EXCLUDE_NUM_BITS) + {} CEncoder::~CEncoder() {} -STDMETHODIMP CEncoder::SetInBufSize(UInt32, UInt32 size) { _bufsNewSizes[BCJ2_NUM_STREAMS] = size; return S_OK; } -STDMETHODIMP CEncoder::SetOutBufSize(UInt32 streamIndex, UInt32 size) { _bufsNewSizes[streamIndex] = size; return S_OK; } +Z7_COM7F_IMF(CEncoder::SetInBufSize(UInt32, UInt32 size)) + { _bufsSizes_New[BCJ2_NUM_STREAMS] = size; return S_OK; } +Z7_COM7F_IMF(CEncoder::SetOutBufSize(UInt32 streamIndex, UInt32 size)) + { _bufsSizes_New[streamIndex] = size; return S_OK; } -STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps) +Z7_COM7F_IMF(CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)) { - UInt32 relatLim = BCJ2_RELAT_LIMIT; - + UInt32 relatLim = BCJ2_ENC_RELAT_LIMIT_DEFAULT; + // UInt32 excludeRangeBits = BCJ2_RELAT_EXCLUDE_NUM_BITS; for (UInt32 i = 0; i < numProps; i++) { const PROPVARIANT &prop = props[i]; - PROPID propID = propIDs[i]; - if (propID >= NCoderPropID::kReduceSize) + const PROPID propID = propIDs[i]; + if (propID >= NCoderPropID::kReduceSize + // && propID != NCoderPropID::kHashBits + ) continue; switch (propID) { @@ -87,225 +101,310 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIA relatLim = (UInt32)1 << v; break; } + case NCoderPropID::kHashBits: + { + if (prop.vt != VT_UI4) + return E_INVALIDARG; + UInt32 v = prop.ulVal; + if (v > 31) + return E_INVALIDARG; + excludeRangeBits = v; + break; + } */ case NCoderPropID::kDictionarySize: { if (prop.vt != VT_UI4) return E_INVALIDARG; relatLim = prop.ulVal; - if (relatLim > ((UInt32)1 << 31)) + if (relatLim > BCJ2_ENC_RELAT_LIMIT_MAX) return E_INVALIDARG; break; } - case NCoderPropID::kNumThreads: - continue; case NCoderPropID::kLevel: continue; - default: return E_INVALIDARG; } } - _relatLim = relatLim; - + // _excludeRangeBits = excludeRangeBits; return S_OK; } -HRESULT CEncoder::CodeReal(ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams, +HRESULT CEncoder::CodeReal( + ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams, ISequentialOutStream * const *outStreams, const UInt64 * const * /* outSizes */, UInt32 numOutStreams, ICompressProgressInfo *progress) { if (numInStreams != 1 || numOutStreams != BCJ2_NUM_STREAMS) return E_INVALIDARG; - RINOK(Alloc()); + RINOK(Alloc()) - UInt32 fileSize_for_Conv = 0; + CBcj2Enc_ip_unsigned fileSize_minus1 = BCJ2_ENC_FileSizeField_UNLIMITED; if (inSizes && inSizes[0]) { - UInt64 inSize = *inSizes[0]; - if (inSize <= BCJ2_FileSize_MAX) - fileSize_for_Conv = (UInt32)inSize; + const UInt64 inSize = *inSizes[0]; + #ifdef BCJ2_ENC_FileSize_MAX + if (inSize <= BCJ2_ENC_FileSize_MAX) + #endif + fileSize_minus1 = BCJ2_ENC_GET_FileSizeField_VAL_FROM_FileSize(inSize); } - CMyComPtr<ICompressGetSubStreamSize> getSubStreamSize; - inStreams[0]->QueryInterface(IID_ICompressGetSubStreamSize, (void **)&getSubStreamSize); + Z7_DECL_CMyComPtr_QI_FROM(ICompressGetSubStreamSize, getSubStreamSize, inStreams[0]) CBcj2Enc enc; - enc.src = _bufs[BCJ2_NUM_STREAMS]; enc.srcLim = enc.src; - { - for (int i = 0; i < BCJ2_NUM_STREAMS; i++) + for (unsigned i = 0; i < BCJ2_NUM_STREAMS; i++) { enc.bufs[i] = _bufs[i]; - enc.lims[i] = _bufs[i] + _bufsCurSizes[i]; + enc.lims[i] = _bufs[i] + _bufsSizes[i]; } } - - size_t numBytes_in_ReadBuf = 0; - UInt64 prevProgress = 0; - UInt64 totalStreamRead = 0; // size read from InputStream - UInt64 currentInPos = 0; // data that was processed, it doesn't include data in input buffer and data in enc.temp - UInt64 outSizeRc = 0; - Bcj2Enc_Init(&enc); - - enc.fileIp = 0; - enc.fileSize = fileSize_for_Conv; - + enc.fileIp64 = 0; + enc.fileSize64_minus1 = fileSize_minus1; enc.relatLimit = _relatLim; - + // enc.relatExcludeBits = _excludeRangeBits; enc.finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE; - bool needSubSize = false; - UInt64 subStreamIndex = 0; - UInt64 subStreamStartPos = 0; + // Varibales that correspond processed data in input stream: + UInt64 inPos_without_Temp = 0; // it doesn't include data in enc.temp[] + UInt64 inPos_with_Temp = 0; // it includes data in enc.temp[] + + UInt64 prevProgress = 0; + UInt64 totalRead = 0; // size read from input stream + UInt64 outSizeRc = 0; + UInt64 subStream_Index = 0; + UInt64 subStream_StartPos = 0; // global start offset of subStreams[subStream_Index] + UInt64 subStream_Size = 0; + const Byte *srcLim_Read = _bufs[BCJ2_NUM_STREAMS]; bool readWasFinished = false; + bool isAccurate = false; + bool wasUnknownSize = false; for (;;) { - if (needSubSize && getSubStreamSize) - { - enc.fileIp = 0; - enc.fileSize = fileSize_for_Conv; - enc.finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE; - - for (;;) - { - UInt64 subStreamSize = 0; - HRESULT result = getSubStreamSize->GetSubStreamSize(subStreamIndex, &subStreamSize); - needSubSize = false; - - if (result == S_OK) - { - UInt64 newEndPos = subStreamStartPos + subStreamSize; - - bool isAccurateEnd = (newEndPos < totalStreamRead || - (newEndPos <= totalStreamRead && readWasFinished)); - - if (newEndPos <= currentInPos && isAccurateEnd) - { - subStreamStartPos = newEndPos; - subStreamIndex++; - continue; - } - - enc.srcLim = _bufs[BCJ2_NUM_STREAMS] + numBytes_in_ReadBuf; - - if (isAccurateEnd) - { - // data in enc.temp is possible here - size_t rem = (size_t)(totalStreamRead - newEndPos); - - /* Pos_of(enc.src) <= old newEndPos <= newEndPos - in another case, it's fail in some code */ - if ((size_t)(enc.srcLim - enc.src) < rem) - return E_FAIL; - - enc.srcLim -= rem; - enc.finishMode = BCJ2_ENC_FINISH_MODE_END_BLOCK; - } - - if (subStreamSize <= BCJ2_FileSize_MAX) - { - enc.fileIp = enc.ip + (UInt32)(subStreamStartPos - currentInPos); - enc.fileSize = (UInt32)subStreamSize; - } - break; - } - - if (result == S_FALSE) - break; - if (result == E_NOTIMPL) - { - getSubStreamSize.Release(); - break; - } - return result; - } - } - - if (readWasFinished && totalStreamRead - currentInPos == Bcj2Enc_Get_InputData_Size(&enc)) + if (readWasFinished && enc.srcLim == srcLim_Read) enc.finishMode = BCJ2_ENC_FINISH_MODE_END_STREAM; + // for debug: + // for (int y=0;y<100;y++) { CBcj2Enc enc2 = enc; Bcj2Enc_Encode(&enc2); } + Bcj2Enc_Encode(&enc); - currentInPos = totalStreamRead - numBytes_in_ReadBuf + (enc.src - _bufs[BCJ2_NUM_STREAMS]) - enc.tempPos; + inPos_with_Temp = totalRead - (size_t)(srcLim_Read - enc.src); + inPos_without_Temp = inPos_with_Temp - Bcj2Enc_Get_AvailInputSize_in_Temp(&enc); + // if (inPos_without_Temp != enc.ip64) return E_FAIL; + if (Bcj2Enc_IsFinished(&enc)) break; if (enc.state < BCJ2_NUM_STREAMS) { - size_t curSize = enc.bufs[enc.state] - _bufs[enc.state]; + if (enc.bufs[enc.state] != enc.lims[enc.state]) + return E_FAIL; + const size_t curSize = (size_t)(enc.bufs[enc.state] - _bufs[enc.state]); // printf("Write stream = %2d %6d\n", enc.state, curSize); - RINOK(WriteStream(outStreams[enc.state], _bufs[enc.state], curSize)); + RINOK(WriteStream(outStreams[enc.state], _bufs[enc.state], curSize)) if (enc.state == BCJ2_STREAM_RC) outSizeRc += curSize; - enc.bufs[enc.state] = _bufs[enc.state]; - enc.lims[enc.state] = _bufs[enc.state] + _bufsCurSizes[enc.state]; + enc.lims[enc.state] = _bufs[enc.state] + _bufsSizes[enc.state]; } - else if (enc.state != BCJ2_ENC_STATE_ORIG) - return E_FAIL; else { - needSubSize = true; - - if (numBytes_in_ReadBuf != (size_t)(enc.src - _bufs[BCJ2_NUM_STREAMS])) + if (enc.state != BCJ2_ENC_STATE_ORIG) + return E_FAIL; + // (enc.state == BCJ2_ENC_STATE_ORIG) + if (enc.src != enc.srcLim) + return E_FAIL; + if (enc.finishMode != BCJ2_ENC_FINISH_MODE_CONTINUE + && Bcj2Enc_Get_AvailInputSize_in_Temp(&enc) != 0) + return E_FAIL; + + if (enc.src == srcLim_Read) { - enc.srcLim = _bufs[BCJ2_NUM_STREAMS] + numBytes_in_ReadBuf; - continue; + if (readWasFinished) + return E_FAIL; + UInt32 curSize = _bufsSizes[BCJ2_NUM_STREAMS]; + RINOK(inStreams[0]->Read(_bufs[BCJ2_NUM_STREAMS], curSize, &curSize)) + // printf("Read %6u bytes\n", curSize); + if (curSize == 0) + readWasFinished = true; + totalRead += curSize; + enc.src = _bufs[BCJ2_NUM_STREAMS]; + srcLim_Read = _bufs[BCJ2_NUM_STREAMS] + curSize; } + enc.srcLim = srcLim_Read; - if (readWasFinished) - continue; - - numBytes_in_ReadBuf = 0; - enc.src = _bufs[BCJ2_NUM_STREAMS]; - enc.srcLim = _bufs[BCJ2_NUM_STREAMS]; - - UInt32 curSize = _bufsCurSizes[BCJ2_NUM_STREAMS]; - RINOK(inStreams[0]->Read(_bufs[BCJ2_NUM_STREAMS], curSize, &curSize)); - - // printf("Read %6d bytes\n", curSize); - if (curSize == 0) + if (getSubStreamSize) { - readWasFinished = true; - continue; - } + /* we set base default conversions options that will be used, + if subStream related options will be not OK */ + enc.fileIp64 = 0; + enc.fileSize64_minus1 = fileSize_minus1; + for (;;) + { + UInt64 nextPos; + if (isAccurate) + nextPos = subStream_StartPos + subStream_Size; + else + { + const HRESULT hres = getSubStreamSize->GetSubStreamSize(subStream_Index, &subStream_Size); + if (hres != S_OK) + { + enc.finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE; + /* if sub-stream size is unknown, we use default settings. + We still can recover to normal mode for next sub-stream, + if GetSubStreamSize() will return S_OK, when current + sub-stream will be finished. + */ + if (hres == S_FALSE) + { + wasUnknownSize = true; + break; + } + if (hres == E_NOTIMPL) + { + getSubStreamSize.Release(); + break; + } + return hres; + } + // printf("GetSubStreamSize %6u : %6u \n", (unsigned)subStream_Index, (unsigned)subStream_Size); + nextPos = subStream_StartPos + subStream_Size; + if ((Int64)subStream_Size == -1) + { + /* it's not expected, but (-1) can mean unknown size. */ + enc.finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE; + wasUnknownSize = true; + break; + } + if (nextPos < subStream_StartPos) + return E_FAIL; + isAccurate = + (nextPos < totalRead + || (nextPos <= totalRead && readWasFinished)); + } + + /* (nextPos) is estimated end position of current sub_stream. + But only (totalRead) and (readWasFinished) values + can confirm that this estimated end position is accurate. + That end position is accurate, if it can't be changed in + further calls of GetSubStreamSize() */ + + /* (nextPos < inPos_with_Temp) is unexpected case here, that we + can get if from some incorrect ICompressGetSubStreamSize object, + where new GetSubStreamSize() call returns smaller size than + confirmed by Read() size from previous GetSubStreamSize() call. + */ + if (nextPos < inPos_with_Temp) + { + if (wasUnknownSize) + { + /* that case can be complicated for recovering. + so we disable sub-streams requesting. */ + enc.finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE; + getSubStreamSize.Release(); + break; + } + return E_FAIL; // to stop after failure + } + + if (nextPos <= inPos_with_Temp) + { + // (nextPos == inPos_with_Temp) + /* CBcj2Enc encoder requires to finish each [non-empty] block (sub-stream) + with BCJ2_ENC_FINISH_MODE_END_BLOCK + or with BCJ2_ENC_FINISH_MODE_END_STREAM for last block: + And we send data of new block to CBcj2Enc, only if previous block was finished. + So we switch to next sub-stream if after Bcj2Enc_Encode() call we have + && (enc.finishMode != BCJ2_ENC_FINISH_MODE_CONTINUE) + && (nextPos == inPos_with_Temp) + && (enc.state == BCJ2_ENC_STATE_ORIG) + */ + if (enc.finishMode != BCJ2_ENC_FINISH_MODE_CONTINUE) + { + /* subStream_StartPos is increased only here. + (subStream_StartPos == inPos_with_Temp) : at start + (subStream_StartPos <= inPos_with_Temp) : will be later + */ + subStream_StartPos = nextPos; + subStream_Size = 0; + wasUnknownSize = false; + subStream_Index++; + isAccurate = false; + // we don't change finishMode here + continue; + } + } + + enc.finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE; + /* for (!isAccurate) case: + (totalRead <= real_end_of_subStream) + so we can use BCJ2_ENC_FINISH_MODE_CONTINUE up to (totalRead) + // we don't change settings at the end of substream, if settings were unknown, + */ + + /* if (wasUnknownSize) then we can't trust size of that sub-stream. + so we use default settings instead */ + if (!wasUnknownSize) + #ifdef BCJ2_ENC_FileSize_MAX + if (subStream_Size <= BCJ2_ENC_FileSize_MAX) + #endif + { + enc.fileIp64 = + (CBcj2Enc_ip_unsigned)( + (CBcj2Enc_ip_signed)enc.ip64 + + (CBcj2Enc_ip_signed)(subStream_StartPos - inPos_without_Temp)); + Bcj2Enc_SET_FileSize(&enc, subStream_Size) + } + + if (isAccurate) + { + /* (real_end_of_subStream == nextPos <= totalRead) + So we can use BCJ2_ENC_FINISH_MODE_END_BLOCK up to (nextPos). */ + const size_t rem = (size_t)(totalRead - nextPos); + if ((size_t)(enc.srcLim - enc.src) < rem) + return E_FAIL; + enc.srcLim -= rem; + enc.finishMode = BCJ2_ENC_FINISH_MODE_END_BLOCK; + } - numBytes_in_ReadBuf = curSize; - totalStreamRead += numBytes_in_ReadBuf; - enc.srcLim = _bufs[BCJ2_NUM_STREAMS] + numBytes_in_ReadBuf; + break; + } // for() loop + } // getSubStreamSize } - if (progress && currentInPos - prevProgress >= (1 << 20)) + if (progress && inPos_without_Temp - prevProgress >= (1 << 22)) { - UInt64 outSize2 = currentInPos + outSizeRc + enc.bufs[BCJ2_STREAM_RC] - enc.bufs[BCJ2_STREAM_RC]; - prevProgress = currentInPos; - // printf("progress %8d, %8d\n", (int)inSize2, (int)outSize2); - RINOK(progress->SetRatioInfo(¤tInPos, &outSize2)); + prevProgress = inPos_without_Temp; + const UInt64 outSize2 = inPos_without_Temp + outSizeRc + + (size_t)(enc.bufs[BCJ2_STREAM_RC] - _bufs[BCJ2_STREAM_RC]); + // printf("progress %8u, %8u\n", (unsigned)inSize2, (unsigned)outSize2); + RINOK(progress->SetRatioInfo(&inPos_without_Temp, &outSize2)) } } - for (int i = 0; i < BCJ2_NUM_STREAMS; i++) + for (unsigned i = 0; i < BCJ2_NUM_STREAMS; i++) { - RINOK(WriteStream(outStreams[i], _bufs[i], enc.bufs[i] - _bufs[i])); + RINOK(WriteStream(outStreams[i], _bufs[i], (size_t)(enc.bufs[i] - _bufs[i]))) } - - // if (currentInPos != subStreamStartPos + subStreamSize) return E_FAIL; - + // if (inPos_without_Temp != subStream_StartPos + subStream_Size) return E_FAIL; return S_OK; } -STDMETHODIMP CEncoder::Code(ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams, + +Z7_COM7F_IMF(CEncoder::Code( + ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams, ISequentialOutStream * const *outStreams, const UInt64 * const *outSizes, UInt32 numOutStreams, - ICompressProgressInfo *progress) + ICompressProgressInfo *progress)) { try { @@ -321,141 +420,170 @@ STDMETHODIMP CEncoder::Code(ISequentialInStream * const *inStreams, const UInt64 -STDMETHODIMP CDecoder::SetInBufSize(UInt32 streamIndex, UInt32 size) { _bufsNewSizes[streamIndex] = size; return S_OK; } -STDMETHODIMP CDecoder::SetOutBufSize(UInt32 , UInt32 size) { _bufsNewSizes[BCJ2_NUM_STREAMS] = size; return S_OK; } - -CDecoder::CDecoder(): _finishMode(false), _outSizeDefined(false), _outSize(0) +CDecoder::CDecoder(): + _finishMode(false) +#ifndef Z7_NO_READ_FROM_CODER + , _outSizeDefined(false) + , _outSize(0) + , _outSize_Processed(0) +#endif {} -STDMETHODIMP CDecoder::SetFinishMode(UInt32 finishMode) +Z7_COM7F_IMF(CDecoder::SetInBufSize(UInt32 streamIndex, UInt32 size)) + { _bufsSizes_New[streamIndex] = size; return S_OK; } +Z7_COM7F_IMF(CDecoder::SetOutBufSize(UInt32, UInt32 size)) + { _bufsSizes_New[BCJ2_NUM_STREAMS] = size; return S_OK; } + +Z7_COM7F_IMF(CDecoder::SetFinishMode(UInt32 finishMode)) { _finishMode = (finishMode != 0); return S_OK; } -void CDecoder::InitCommon() +void CBaseDecoder::InitCommon() { + for (unsigned i = 0; i < BCJ2_NUM_STREAMS; i++) { - for (int i = 0; i < BCJ2_NUM_STREAMS; i++) - dec.lims[i] = dec.bufs[i] = _bufs[i]; + dec.lims[i] = dec.bufs[i] = _bufs[i]; + _readRes[i] = S_OK; + _extraSizes[i] = 0; + _readSizes[i] = 0; } + Bcj2Dec_Init(&dec); +} + +/* call ReadInStream() only after Bcj2Dec_Decode(). + input requirement: + (dec.state < BCJ2_NUM_STREAMS) +*/ +void CBaseDecoder::ReadInStream(ISequentialInStream *inStream) +{ + const unsigned state = dec.state; + UInt32 total; { - for (int i = 0; i < BCJ2_NUM_STREAMS; i++) + Byte *buf = _bufs[state]; + const Byte *cur = dec.bufs[state]; + // if (cur != dec.lims[state]) throw 1; // unexpected case + dec.lims[state] = + dec.bufs[state] = buf; + total = (UInt32)_extraSizes[state]; + for (UInt32 i = 0; i < total; i++) + buf[i] = cur[i]; + } + + if (_readRes[state] != S_OK) + return; + + do + { + UInt32 curSize = _bufsSizes[state] - total; + // if (state == 0) curSize = 0; // for debug + // curSize = 7; // for debug + /* even if we have reached provided inSizes[state] limit, + we call Read() with (curSize != 0), because + we want the called handler of stream->Read() could + execute required Init/Flushing code even for empty stream. + In another way we could call Read() with (curSize == 0) for + finished streams, but some Read() handlers can ignore Read(size=0) calls. + */ + const HRESULT hres = inStream->Read(_bufs[state] + total, curSize, &curSize); + _readRes[state] = hres; + if (curSize == 0) + break; + _readSizes[state] += curSize; + total += curSize; + if (hres != S_OK) + break; + } + while (total < 4 && BCJ2_IS_32BIT_STREAM(state)); + + /* we exit from decoding loop here, if we can't + provide new data for input stream. + Usually it's normal exit after full stream decoding. */ + if (total == 0) + return; + + if (BCJ2_IS_32BIT_STREAM(state)) + { + const unsigned extra = ((unsigned)total & 3); + _extraSizes[state] = extra; + if (total < 4) { - _extraReadSizes[i] = 0; - _inStreamsProcessed[i] = 0; - _readRes[i] = S_OK; + if (_readRes[state] == S_OK) + _readRes[state] = S_FALSE; // actually it's stream error. So maybe we need another error code. + return; } + total -= extra; } - - Bcj2Dec_Init(&dec); + + dec.lims[state] += total; // = _bufs[state] + total; } -HRESULT CDecoder::Code(ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams, + +Z7_COM7F_IMF(CDecoder::Code( + ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams, ISequentialOutStream * const *outStreams, const UInt64 * const *outSizes, UInt32 numOutStreams, - ICompressProgressInfo *progress) + ICompressProgressInfo *progress)) { if (numInStreams != BCJ2_NUM_STREAMS || numOutStreams != 1) return E_INVALIDARG; - RINOK(Alloc()); - + RINOK(Alloc()) InitCommon(); dec.destLim = dec.dest = _bufs[BCJ2_NUM_STREAMS]; - UInt64 outSizeProcessed = 0; + UInt64 outSizeWritten = 0; UInt64 prevProgress = 0; - HRESULT res = S_OK; + HRESULT hres_Crit = S_OK; // critical hres status (mostly from input stream reading) + HRESULT hres_Weak = S_OK; // first non-critical error code from input stream reading for (;;) { if (Bcj2Dec_Decode(&dec) != SZ_OK) - return S_FALSE; - + { + /* it's possible only at start (first 5 bytes in RC stream) */ + hres_Crit = S_FALSE; + break; + } if (dec.state < BCJ2_NUM_STREAMS) { - size_t totalRead = _extraReadSizes[dec.state]; + ReadInStream(inStreams[dec.state]); + const unsigned state = dec.state; + const HRESULT hres = _readRes[state]; + if (dec.lims[state] == _bufs[state]) { - Byte *buf = _bufs[dec.state]; - for (size_t i = 0; i < totalRead; i++) - buf[i] = dec.bufs[dec.state][i]; - dec.lims[dec.state] = - dec.bufs[dec.state] = buf; - } - - if (_readRes[dec.state] != S_OK) - { - res = _readRes[dec.state]; + // we break decoding, if there are no new data in input stream + hres_Crit = hres; break; } - - do - { - UInt32 curSize = _bufsCurSizes[dec.state] - (UInt32)totalRead; - /* - we want to call Read even even if size is 0 - if (inSizes && inSizes[dec.state]) - { - UInt64 rem = *inSizes[dec.state] - _inStreamsProcessed[dec.state]; - if (curSize > rem) - curSize = (UInt32)rem; - } - */ - - HRESULT res2 = inStreams[dec.state]->Read(_bufs[dec.state] + totalRead, curSize, &curSize); - _readRes[dec.state] = res2; - if (curSize == 0) - break; - _inStreamsProcessed[dec.state] += curSize; - totalRead += curSize; - if (res2 != S_OK) - break; - } - while (totalRead < 4 && BCJ2_IS_32BIT_STREAM(dec.state)); - - if (_readRes[dec.state] != S_OK) - res = _readRes[dec.state]; - - if (totalRead == 0) - break; - - // res == S_OK; - - if (BCJ2_IS_32BIT_STREAM(dec.state)) - { - unsigned extraSize = ((unsigned)totalRead & 3); - _extraReadSizes[dec.state] = extraSize; - if (totalRead < 4) - { - res = (_readRes[dec.state] != S_OK) ? _readRes[dec.state] : S_FALSE; - break; - } - totalRead -= extraSize; - } - - dec.lims[dec.state] = _bufs[dec.state] + totalRead; + if (hres != S_OK && hres_Weak == S_OK) + hres_Weak = hres; } - else // if (dec.state <= BCJ2_STATE_ORIG) + else // (BCJ2_DEC_STATE_ORIG_0 <= state <= BCJ2_STATE_ORIG) { - size_t curSize = dec.dest - _bufs[BCJ2_NUM_STREAMS]; - if (curSize != 0) { - outSizeProcessed += curSize; - RINOK(WriteStream(outStreams[0], _bufs[BCJ2_NUM_STREAMS], curSize)); + const size_t curSize = (size_t)(dec.dest - _bufs[BCJ2_NUM_STREAMS]); + if (curSize != 0) + { + outSizeWritten += curSize; + RINOK(WriteStream(outStreams[0], _bufs[BCJ2_NUM_STREAMS], curSize)) + } } - dec.dest = _bufs[BCJ2_NUM_STREAMS]; { - size_t rem = _bufsCurSizes[BCJ2_NUM_STREAMS]; + UInt32 rem = _bufsSizes[BCJ2_NUM_STREAMS]; if (outSizes && outSizes[0]) { - UInt64 outSize = *outSizes[0] - outSizeProcessed; + const UInt64 outSize = *outSizes[0] - outSizeWritten; if (rem > outSize) - rem = (size_t)outSize; + rem = (UInt32)outSize; } + dec.dest = _bufs[BCJ2_NUM_STREAMS]; dec.destLim = dec.dest + rem; + /* we exit from decoding loop here, + if (outSizes[0]) limit for output stream was reached */ if (rem == 0) break; } @@ -463,47 +591,67 @@ HRESULT CDecoder::Code(ISequentialInStream * const *inStreams, const UInt64 * co if (progress) { - UInt64 outSize2 = outSizeProcessed + (dec.dest - _bufs[BCJ2_NUM_STREAMS]); - if (outSize2 - prevProgress >= (1 << 22)) + // here we don't count additional data in dec.temp (up to 4 bytes for output stream) + const UInt64 processed = outSizeWritten + (size_t)(dec.dest - _bufs[BCJ2_NUM_STREAMS]); + if (processed - prevProgress >= (1 << 24)) { - UInt64 inSize2 = outSize2 + _inStreamsProcessed[BCJ2_STREAM_RC] - (dec.lims[BCJ2_STREAM_RC] - dec.bufs[BCJ2_STREAM_RC]); - RINOK(progress->SetRatioInfo(&inSize2, &outSize2)); - prevProgress = outSize2; + prevProgress = processed; + const UInt64 inSize = processed + + _readSizes[BCJ2_STREAM_RC] - (size_t)( + dec.lims[BCJ2_STREAM_RC] - + dec.bufs[BCJ2_STREAM_RC]); + RINOK(progress->SetRatioInfo(&inSize, &prevProgress)) } } } - size_t curSize = dec.dest - _bufs[BCJ2_NUM_STREAMS]; - if (curSize != 0) { - outSizeProcessed += curSize; - RINOK(WriteStream(outStreams[0], _bufs[BCJ2_NUM_STREAMS], curSize)); + const size_t curSize = (size_t)(dec.dest - _bufs[BCJ2_NUM_STREAMS]); + if (curSize != 0) + { + outSizeWritten += curSize; + RINOK(WriteStream(outStreams[0], _bufs[BCJ2_NUM_STREAMS], curSize)) + } } - if (res != S_OK) - return res; + if (hres_Crit == S_OK) hres_Crit = hres_Weak; + if (hres_Crit != S_OK) return hres_Crit; if (_finishMode) { - if (!Bcj2Dec_IsFinished(&dec)) + if (!Bcj2Dec_IsMaybeFinished_code(&dec)) return S_FALSE; - // we still allow the cases when input streams are larger than required for decoding. - // so the case (dec.state == BCJ2_STATE_ORIG) is also allowed, if MAIN stream is larger than required. - if (dec.state != BCJ2_STREAM_MAIN && - dec.state != BCJ2_DEC_STATE_ORIG) + /* here we support two correct ways to finish full stream decoding + with one of the following conditions: + - the end of input stream MAIN was reached + - the end of output stream ORIG was reached + Currently 7-Zip/7z code ends with (state == BCJ2_STREAM_MAIN), + because the sizes of MAIN and ORIG streams are known and these + sizes are stored in 7z archive headers. + And Bcj2Dec_Decode() exits with (state == BCJ2_STREAM_MAIN), + if both MAIN and ORIG streams have reached buffers limits. + But if the size of MAIN stream is not known or if the + size of MAIN stream includes some padding after payload data, + then we still can correctly finish decoding with + (state == BCJ2_DEC_STATE_ORIG), if we know the exact size + of output ORIG stream. + */ + if (dec.state != BCJ2_STREAM_MAIN) + if (dec.state != BCJ2_DEC_STATE_ORIG) + return S_FALSE; + + /* the caller also will know written size. + So the following check is optional: */ + if (outSizes && outSizes[0] && *outSizes[0] != outSizeWritten) return S_FALSE; if (inSizes) { - for (int i = 0; i < BCJ2_NUM_STREAMS; i++) + for (unsigned i = 0; i < BCJ2_NUM_STREAMS; i++) { - size_t rem = dec.lims[i] - dec.bufs[i] + _extraReadSizes[i]; - /* - if (rem != 0) - return S_FALSE; - */ - if (inSizes[i] && *inSizes[i] != _inStreamsProcessed[i] - rem) + /* if (inSizes[i]) is defined, we do full check for processed stream size. */ + if (inSizes[i] && *inSizes[i] != GetProcessedSize_ForInStream(i)) return S_FALSE; } } @@ -512,49 +660,65 @@ HRESULT CDecoder::Code(ISequentialInStream * const *inStreams, const UInt64 * co return S_OK; } -STDMETHODIMP CDecoder::SetInStream2(UInt32 streamIndex, ISequentialInStream *inStream) + +Z7_COM7F_IMF(CDecoder::GetInStreamProcessedSize2(UInt32 streamIndex, UInt64 *value)) +{ + *value = GetProcessedSize_ForInStream(streamIndex); + return S_OK; +} + + +#ifndef Z7_NO_READ_FROM_CODER + +Z7_COM7F_IMF(CDecoder::SetInStream2(UInt32 streamIndex, ISequentialInStream *inStream)) { _inStreams[streamIndex] = inStream; return S_OK; } -STDMETHODIMP CDecoder::ReleaseInStream2(UInt32 streamIndex) +Z7_COM7F_IMF(CDecoder::ReleaseInStream2(UInt32 streamIndex)) { _inStreams[streamIndex].Release(); return S_OK; } -STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize) +Z7_COM7F_IMF(CDecoder::SetOutStreamSize(const UInt64 *outSize)) { _outSizeDefined = (outSize != NULL); _outSize = 0; if (_outSizeDefined) _outSize = *outSize; - _outSize_Processed = 0; - HRESULT res = Alloc(false); - + const HRESULT res = Alloc(false); // allocForOrig InitCommon(); dec.destLim = dec.dest = NULL; - return res; } -STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; - if (size == 0) - return S_OK; + /* Note the case: + The output (ORIG) stream can be empty. + But BCJ2_STREAM_RC stream always is not empty. + And we want to support full data processing for all streams. + We disable check (size == 0) here. + So if the caller calls this CDecoder::Read() with (size == 0), + we execute required Init/Flushing code in this CDecoder object. + Also this CDecoder::Read() function will call Read() for input streams. + So the handlers of input streams objects also can do Init/Flushing. + */ + // if (size == 0) return S_OK; // disabled to allow (size == 0) processing UInt32 totalProcessed = 0; if (_outSizeDefined) { - UInt64 rem = _outSize - _outSize_Processed; + const UInt64 rem = _outSize - _outSize_Processed; if (size > rem) size = (UInt32)rem; } @@ -565,94 +729,125 @@ STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize) for (;;) { - SRes sres = Bcj2Dec_Decode(&dec); - if (sres != SZ_OK) - return S_FALSE; - + if (Bcj2Dec_Decode(&dec) != SZ_OK) + return S_FALSE; // this error can be only at start of stream { - UInt32 curSize = (UInt32)(dec.dest - (Byte *)data); + const UInt32 curSize = (UInt32)(size_t)(dec.dest - (Byte *)data); if (curSize != 0) { - totalProcessed += curSize; - if (processedSize) - *processedSize = totalProcessed; data = (void *)((Byte *)data + curSize); size -= curSize; _outSize_Processed += curSize; + totalProcessed += curSize; + if (processedSize) + *processedSize = totalProcessed; } } - if (dec.state >= BCJ2_NUM_STREAMS) break; - + ReadInStream(_inStreams[dec.state]); + if (dec.lims[dec.state] == _bufs[dec.state]) { - size_t totalRead = _extraReadSizes[dec.state]; - { - Byte *buf = _bufs[dec.state]; - for (size_t i = 0; i < totalRead; i++) - buf[i] = dec.bufs[dec.state][i]; - dec.lims[dec.state] = - dec.bufs[dec.state] = buf; - } - - if (_readRes[dec.state] != S_OK) - return _readRes[dec.state]; - - do - { - UInt32 curSize = _bufsCurSizes[dec.state] - (UInt32)totalRead; - HRESULT res2 = _inStreams[dec.state]->Read(_bufs[dec.state] + totalRead, curSize, &curSize); - _readRes[dec.state] = res2; - if (curSize == 0) - break; - _inStreamsProcessed[dec.state] += curSize; - totalRead += curSize; - if (res2 != S_OK) - break; - } - while (totalRead < 4 && BCJ2_IS_32BIT_STREAM(dec.state)); - - if (totalRead == 0) - { - if (totalProcessed == 0) - res = _readRes[dec.state]; - break; - } - - if (BCJ2_IS_32BIT_STREAM(dec.state)) - { - unsigned extraSize = ((unsigned)totalRead & 3); - _extraReadSizes[dec.state] = extraSize; - if (totalRead < 4) - { - if (totalProcessed != 0) - return S_OK; - return (_readRes[dec.state] != S_OK) ? _readRes[dec.state] : S_FALSE; - } - totalRead -= extraSize; - } - - dec.lims[dec.state] = _bufs[dec.state] + totalRead; + /* we break decoding, if there are no new data in input stream. + and we ignore error code, if some data were written to output buffer. */ + if (totalProcessed == 0) + res = _readRes[dec.state]; + break; } } + if (res == S_OK) if (_finishMode && _outSizeDefined && _outSize == _outSize_Processed) { - if (!Bcj2Dec_IsFinished(&dec)) + if (!Bcj2Dec_IsMaybeFinished_code(&dec)) return S_FALSE; - - if (dec.state != BCJ2_STREAM_MAIN && - dec.state != BCJ2_DEC_STATE_ORIG) + if (dec.state != BCJ2_STREAM_MAIN) + if (dec.state != BCJ2_DEC_STATE_ORIG) return S_FALSE; - - /* - for (int i = 0; i < BCJ2_NUM_STREAMS; i++) - if (dec.bufs[i] != dec.lims[i] || _extraReadSizes[i] != 0) - return S_FALSE; - */ } return res; } +#endif + }} + + +/* +extern "C" +{ +extern UInt32 bcj2_stats[256 + 2][2]; +} + +static class CBcj2Stat +{ +public: + ~CBcj2Stat() + { + printf("\nBCJ2 stat:"); + unsigned sums[2] = { 0, 0 }; + int i; + for (i = 2; i < 256 + 2; i++) + { + sums[0] += bcj2_stats[i][0]; + sums[1] += bcj2_stats[i][1]; + } + const unsigned sums2 = sums[0] + sums[1]; + for (int vi = 0; vi < 256 + 3; vi++) + { + printf("\n"); + UInt32 n0, n1; + if (vi < 4) + printf("\n"); + + if (vi < 2) + i = vi; + else if (vi == 2) + i = -1; + else + i = vi - 1; + + if (i < 0) + { + n0 = sums[0]; + n1 = sums[1]; + printf("calls :"); + } + else + { + if (i == 0) + printf("jcc :"); + else if (i == 1) + printf("jump :"); + else + printf("call %02x :", i - 2); + n0 = bcj2_stats[i][0]; + n1 = bcj2_stats[i][1]; + } + + const UInt32 sum = n0 + n1; + printf(" %10u", sum); + + #define PRINT_PERC(val, sum) \ + { UInt32 _sum = sum; if (_sum == 0) _sum = 1; \ + printf(" %7.3f %%", (double)((double)val * (double)100 / (double)_sum )); } + + if (i >= 2 || i < 0) + { + PRINT_PERC(sum, sums2); + } + else + printf("%10s", ""); + + printf(" :%10u", n0); + PRINT_PERC(n0, sum); + + printf(" :%10u", n1); + PRINT_PERC(n1, sum); + } + printf("\n\n"); + fflush(stdout); + } +} g_CBcjStat; +*/ diff --git a/3rdparty/lzma/CPP/7zip/Compress/Bcj2Coder.h b/3rdparty/lzma/CPP/7zip/Compress/Bcj2Coder.h index 381b9f54a57..2ab91bc871c 100644 --- a/3rdparty/lzma/CPP/7zip/Compress/Bcj2Coder.h +++ b/3rdparty/lzma/CPP/7zip/Compress/Bcj2Coder.h @@ -1,7 +1,7 @@ // Bcj2Coder.h -#ifndef __COMPRESS_BCJ2_CODER_H -#define __COMPRESS_BCJ2_CODER_H +#ifndef ZIP7_INC_COMPRESS_BCJ2_CODER_H +#define ZIP7_INC_COMPRESS_BCJ2_CODER_H #include "../../../C/Bcj2.h" @@ -16,8 +16,8 @@ class CBaseCoder { protected: Byte *_bufs[BCJ2_NUM_STREAMS + 1]; - UInt32 _bufsCurSizes[BCJ2_NUM_STREAMS + 1]; - UInt32 _bufsNewSizes[BCJ2_NUM_STREAMS + 1]; + UInt32 _bufsSizes[BCJ2_NUM_STREAMS + 1]; + UInt32 _bufsSizes_New[BCJ2_NUM_STREAMS + 1]; HRESULT Alloc(bool allocForOrig = true); public: @@ -26,89 +26,99 @@ public: }; -#ifndef EXTRACT_ONLY +#ifndef Z7_EXTRACT_ONLY -class CEncoder: +class CEncoder Z7_final: public ICompressCoder2, public ICompressSetCoderProperties, public ICompressSetBufSize, public CMyUnknownImp, public CBaseCoder { + Z7_IFACES_IMP_UNK_3( + ICompressCoder2, + ICompressSetCoderProperties, + ICompressSetBufSize) + UInt32 _relatLim; + // UInt32 _excludeRangeBits; - HRESULT CodeReal(ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams, + HRESULT CodeReal( + ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams, ISequentialOutStream * const *outStreams, const UInt64 * const *outSizes, UInt32 numOutStreams, ICompressProgressInfo *progress); - public: - MY_UNKNOWN_IMP3(ICompressCoder2, ICompressSetCoderProperties, ICompressSetBufSize) - - STDMETHOD(Code)(ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams, - ISequentialOutStream * const *outStreams, const UInt64 * const *outSizes, UInt32 numOutStreams, - ICompressProgressInfo *progress); - - STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); - - STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size); - STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size); - CEncoder(); ~CEncoder(); }; #endif -class CDecoder: + + +class CBaseDecoder: public CBaseCoder +{ +protected: + HRESULT _readRes[BCJ2_NUM_STREAMS]; + unsigned _extraSizes[BCJ2_NUM_STREAMS]; + UInt64 _readSizes[BCJ2_NUM_STREAMS]; + + CBcj2Dec dec; + + UInt64 GetProcessedSize_ForInStream(unsigned i) const + { + return _readSizes[i] - ((size_t)(dec.lims[i] - dec.bufs[i]) + _extraSizes[i]); + } + void InitCommon(); + void ReadInStream(ISequentialInStream *inStream); +}; + + +class CDecoder Z7_final: public ICompressCoder2, public ICompressSetFinishMode, + public ICompressGetInStreamProcessedSize2, + public ICompressSetBufSize, +#ifndef Z7_NO_READ_FROM_CODER public ICompressSetInStream2, - public ISequentialInStream, public ICompressSetOutStreamSize, - public ICompressSetBufSize, + public ISequentialInStream, +#endif public CMyUnknownImp, - public CBaseCoder + public CBaseDecoder { - unsigned _extraReadSizes[BCJ2_NUM_STREAMS]; - UInt64 _inStreamsProcessed[BCJ2_NUM_STREAMS]; - HRESULT _readRes[BCJ2_NUM_STREAMS]; - CMyComPtr<ISequentialInStream> _inStreams[BCJ2_NUM_STREAMS]; + Z7_COM_QI_BEGIN2(ICompressCoder2) + Z7_COM_QI_ENTRY(ICompressSetFinishMode) + Z7_COM_QI_ENTRY(ICompressGetInStreamProcessedSize2) + Z7_COM_QI_ENTRY(ICompressSetBufSize) + #ifndef Z7_NO_READ_FROM_CODER + Z7_COM_QI_ENTRY(ICompressSetInStream2) + Z7_COM_QI_ENTRY(ICompressSetOutStreamSize) + Z7_COM_QI_ENTRY(ISequentialInStream) + #endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(ICompressCoder2) + Z7_IFACE_COM7_IMP(ICompressSetFinishMode) + Z7_IFACE_COM7_IMP(ICompressGetInStreamProcessedSize2) + Z7_IFACE_COM7_IMP(ICompressSetBufSize) +#ifndef Z7_NO_READ_FROM_CODER + Z7_IFACE_COM7_IMP(ICompressSetInStream2) + Z7_IFACE_COM7_IMP(ICompressSetOutStreamSize) + Z7_IFACE_COM7_IMP(ISequentialInStream) +#endif bool _finishMode; + +#ifndef Z7_NO_READ_FROM_CODER bool _outSizeDefined; UInt64 _outSize; UInt64 _outSize_Processed; - CBcj2Dec dec; - - void InitCommon(); - // HRESULT ReadSpec(); - + CMyComPtr<ISequentialInStream> _inStreams[BCJ2_NUM_STREAMS]; +#endif + public: - MY_UNKNOWN_IMP6( - ICompressCoder2, - ICompressSetFinishMode, - ICompressSetInStream2, - ISequentialInStream, - ICompressSetOutStreamSize, - ICompressSetBufSize - ); - - STDMETHOD(Code)(ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams, - ISequentialOutStream * const *outStreams, const UInt64 * const *outSizes, UInt32 numOutStreams, - ICompressProgressInfo *progress); - - STDMETHOD(SetFinishMode)(UInt32 finishMode); - - STDMETHOD(SetInStream2)(UInt32 streamIndex, ISequentialInStream *inStream); - STDMETHOD(ReleaseInStream2)(UInt32 streamIndex); - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - - STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); - - STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size); - STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size); - CDecoder(); }; diff --git a/3rdparty/lzma/CPP/7zip/Compress/Bcj2Register.cpp b/3rdparty/lzma/CPP/7zip/Compress/Bcj2Register.cpp index 7a48f91cfac..1ce4decb257 100644 --- a/3rdparty/lzma/CPP/7zip/Compress/Bcj2Register.cpp +++ b/3rdparty/lzma/CPP/7zip/Compress/Bcj2Register.cpp @@ -10,13 +10,13 @@ namespace NCompress { namespace NBcj2 { REGISTER_CODEC_CREATE_2(CreateCodec, CDecoder(), ICompressCoder2) -#ifndef EXTRACT_ONLY +#ifndef Z7_EXTRACT_ONLY REGISTER_CODEC_CREATE_2(CreateCodecOut, CEncoder(), ICompressCoder2) #else #define CreateCodecOut NULL #endif -REGISTER_CODEC_VAR +REGISTER_CODEC_VAR(BCJ2) { CreateCodec, CreateCodecOut, 0x303011B, "BCJ2", 4, false }; REGISTER_CODEC(BCJ2) diff --git a/3rdparty/lzma/CPP/7zip/Compress/BcjCoder.cpp b/3rdparty/lzma/CPP/7zip/Compress/BcjCoder.cpp index 32aa1762cdd..00478747408 100644 --- a/3rdparty/lzma/CPP/7zip/Compress/BcjCoder.cpp +++ b/3rdparty/lzma/CPP/7zip/Compress/BcjCoder.cpp @@ -7,17 +7,17 @@ namespace NCompress { namespace NBcj { -STDMETHODIMP CCoder::Init() +Z7_COM7F_IMF(CCoder2::Init()) { - _bufferPos = 0; - x86_Convert_Init(_prevMask); + _pc = 0; + _state = Z7_BRANCH_CONV_ST_X86_STATE_INIT_VAL; return S_OK; } -STDMETHODIMP_(UInt32) CCoder::Filter(Byte *data, UInt32 size) +Z7_COM7F_IMF2(UInt32, CCoder2::Filter(Byte *data, UInt32 size)) { - UInt32 processed = (UInt32)::x86_Convert(data, size, _bufferPos, &_prevMask, _encode); - _bufferPos += processed; + const UInt32 processed = (UInt32)(size_t)(_convFunc(data, size, _pc, &_state) - data); + _pc += processed; return processed; } diff --git a/3rdparty/lzma/CPP/7zip/Compress/BcjCoder.h b/3rdparty/lzma/CPP/7zip/Compress/BcjCoder.h index 7883906e4a0..734a2786694 100644 --- a/3rdparty/lzma/CPP/7zip/Compress/BcjCoder.h +++ b/3rdparty/lzma/CPP/7zip/Compress/BcjCoder.h @@ -1,7 +1,7 @@ // BcjCoder.h -#ifndef __COMPRESS_BCJ_CODER_H -#define __COMPRESS_BCJ_CODER_H +#ifndef ZIP7_INC_COMPRESS_BCJ_CODER_H +#define ZIP7_INC_COMPRESS_BCJ_CODER_H #include "../../../C/Bra.h" @@ -12,18 +12,24 @@ namespace NCompress { namespace NBcj { -class CCoder: - public ICompressFilter, - public CMyUnknownImp -{ - UInt32 _bufferPos; - UInt32 _prevMask; - int _encode; +/* CCoder in old versions used another constructor parameter CCoder(int encode). + And some code called it as CCoder(0). + We have changed constructor parameter type. + So we have changed the name of class also to CCoder2. */ + +Z7_CLASS_IMP_COM_1( + CCoder2 + , ICompressFilter +) + UInt32 _pc; + UInt32 _state; + z7_Func_BranchConvSt _convFunc; public: - MY_UNKNOWN_IMP1(ICompressFilter); - INTERFACE_ICompressFilter(;) - - CCoder(int encode): _bufferPos(0), _encode(encode) { x86_Convert_Init(_prevMask); } + CCoder2(z7_Func_BranchConvSt convFunc): + _pc(0), + _state(Z7_BRANCH_CONV_ST_X86_STATE_INIT_VAL), + _convFunc(convFunc) + {} }; }} diff --git a/3rdparty/lzma/CPP/7zip/Compress/BcjRegister.cpp b/3rdparty/lzma/CPP/7zip/Compress/BcjRegister.cpp index f06dcfe9f6d..0348f641fd0 100644 --- a/3rdparty/lzma/CPP/7zip/Compress/BcjRegister.cpp +++ b/3rdparty/lzma/CPP/7zip/Compress/BcjRegister.cpp @@ -10,8 +10,8 @@ namespace NCompress { namespace NBcj { REGISTER_FILTER_E(BCJ, - CCoder(false), - CCoder(true), + CCoder2(z7_BranchConvSt_X86_Dec), + CCoder2(z7_BranchConvSt_X86_Enc), 0x3030103, "BCJ") }} diff --git a/3rdparty/lzma/CPP/7zip/Compress/BranchMisc.cpp b/3rdparty/lzma/CPP/7zip/Compress/BranchMisc.cpp index d0e75e83bf1..d9fec8c51a0 100644 --- a/3rdparty/lzma/CPP/7zip/Compress/BranchMisc.cpp +++ b/3rdparty/lzma/CPP/7zip/Compress/BranchMisc.cpp @@ -2,22 +2,109 @@ #include "StdAfx.h" +#include "../../../C/CpuArch.h" + +#include "../Common/StreamUtils.h" + #include "BranchMisc.h" namespace NCompress { namespace NBranch { -STDMETHODIMP CCoder::Init() +Z7_COM7F_IMF(CCoder::Init()) +{ + _pc = 0; + return S_OK; +} + + +Z7_COM7F_IMF2(UInt32, CCoder::Filter(Byte *data, UInt32 size)) +{ + const UInt32 processed = (UInt32)(size_t)(BraFunc(data, size, _pc) - data); + _pc += processed; + return processed; +} + + +namespace NArm64 { + +#ifndef Z7_EXTRACT_ONLY + +Z7_COM7F_IMF(CEncoder::Init()) +{ + _pc = _pc_Init; + return S_OK; +} + +Z7_COM7F_IMF2(UInt32, CEncoder::Filter(Byte *data, UInt32 size)) +{ + const UInt32 processed = (UInt32)(size_t)(Z7_BRANCH_CONV_ENC(ARM64)(data, size, _pc) - data); + _pc += processed; + return processed; +} + +Z7_COM7F_IMF(CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)) { - _bufferPos = 0; + UInt32 pc = 0; + for (UInt32 i = 0; i < numProps; i++) + { + const PROPID propID = propIDs[i]; + if (propID == NCoderPropID::kDefaultProp || + propID == NCoderPropID::kBranchOffset) + { + const PROPVARIANT &prop = props[i]; + if (prop.vt != VT_UI4) + return E_INVALIDARG; + pc = prop.ulVal; + if ((pc & 3) != 0) + return E_INVALIDARG; + } + } + _pc_Init = pc; return S_OK; } -STDMETHODIMP_(UInt32) CCoder::Filter(Byte *data, UInt32 size) + +Z7_COM7F_IMF(CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)) +{ + if (_pc_Init == 0) + return S_OK; + Byte buf[4]; + SetUi32(buf, _pc_Init) + return WriteStream(outStream, buf, 4); +} + +#endif + + +Z7_COM7F_IMF(CDecoder::Init()) { - UInt32 processed = (UInt32)BraFunc(data, size, _bufferPos, _encode); - _bufferPos += processed; + _pc = _pc_Init; + return S_OK; +} + +Z7_COM7F_IMF2(UInt32, CDecoder::Filter(Byte *data, UInt32 size)) +{ + const UInt32 processed = (UInt32)(size_t)(Z7_BRANCH_CONV_DEC(ARM64)(data, size, _pc) - data); + _pc += processed; return processed; } +Z7_COM7F_IMF(CDecoder::SetDecoderProperties2(const Byte *props, UInt32 size)) +{ + UInt32 val = 0; + if (size != 0) + { + if (size != 4) + return E_NOTIMPL; + val = GetUi32(props); + if ((val & 3) != 0) + return E_NOTIMPL; + } + _pc_Init = val; + return S_OK; +} + +} + }} diff --git a/3rdparty/lzma/CPP/7zip/Compress/BranchMisc.h b/3rdparty/lzma/CPP/7zip/Compress/BranchMisc.h index 66fc23d2cd1..a5793f729d3 100644 --- a/3rdparty/lzma/CPP/7zip/Compress/BranchMisc.h +++ b/3rdparty/lzma/CPP/7zip/Compress/BranchMisc.h @@ -1,35 +1,57 @@ // BranchMisc.h -#ifndef __COMPRESS_BRANCH_MISC_H -#define __COMPRESS_BRANCH_MISC_H +#ifndef ZIP7_INC_COMPRESS_BRANCH_MISC_H +#define ZIP7_INC_COMPRESS_BRANCH_MISC_H +#include "../../../C/Bra.h" #include "../../Common/MyCom.h" #include "../ICoder.h" -EXTERN_C_BEGIN +namespace NCompress { +namespace NBranch { -typedef SizeT (*Func_Bra)(Byte *data, SizeT size, UInt32 ip, int encoding); +Z7_CLASS_IMP_COM_1( + CCoder + , ICompressFilter +) + UInt32 _pc; + z7_Func_BranchConv BraFunc; +public: + CCoder(z7_Func_BranchConv bra): _pc(0), BraFunc(bra) {} +}; -EXTERN_C_END +namespace NArm64 { -namespace NCompress { -namespace NBranch { +#ifndef Z7_EXTRACT_ONLY -class CCoder: - public ICompressFilter, - public CMyUnknownImp -{ - UInt32 _bufferPos; - int _encode; - Func_Bra BraFunc; +Z7_CLASS_IMP_COM_3( + CEncoder + , ICompressFilter + , ICompressSetCoderProperties + , ICompressWriteCoderProperties +) + UInt32 _pc; + UInt32 _pc_Init; public: - MY_UNKNOWN_IMP1(ICompressFilter); - INTERFACE_ICompressFilter(;) + CEncoder(): _pc(0), _pc_Init(0) {} +}; + +#endif - CCoder(Func_Bra bra, int encode): _bufferPos(0), _encode(encode), BraFunc(bra) {} +Z7_CLASS_IMP_COM_2( + CDecoder + , ICompressFilter + , ICompressSetDecoderProperties2 +) + UInt32 _pc; + UInt32 _pc_Init; +public: + CDecoder(): _pc(0), _pc_Init(0) {} }; +} + }} #endif diff --git a/3rdparty/lzma/CPP/7zip/Compress/BranchRegister.cpp b/3rdparty/lzma/CPP/7zip/Compress/BranchRegister.cpp index 6331c1b9e12..80fbf60ab78 100644 --- a/3rdparty/lzma/CPP/7zip/Compress/BranchRegister.cpp +++ b/3rdparty/lzma/CPP/7zip/Compress/BranchRegister.cpp @@ -2,8 +2,6 @@ #include "StdAfx.h" -#include "../../../C/Bra.h" - #include "../Common/RegisterCodec.h" #include "BranchMisc.h" @@ -11,9 +9,18 @@ namespace NCompress { namespace NBranch { +#ifdef Z7_EXTRACT_ONLY +#define GET_CREATE_FUNC(x) NULL +#define CREATE_BRA_E(n) +#else +#define GET_CREATE_FUNC(x) x +#define CREATE_BRA_E(n) \ + REGISTER_FILTER_CREATE(CreateBra_Encoder_ ## n, CCoder(Z7_BRANCH_CONV_ENC(n))) +#endif + #define CREATE_BRA(n) \ - REGISTER_FILTER_CREATE(CreateBra_Decoder_ ## n, CCoder(n ## _Convert, false)) \ - REGISTER_FILTER_CREATE(CreateBra_Encoder_ ## n, CCoder(n ## _Convert, true)) \ + REGISTER_FILTER_CREATE(CreateBra_Decoder_ ## n, CCoder(Z7_BRANCH_CONV_DEC(n))) \ + CREATE_BRA_E(n) CREATE_BRA(PPC) CREATE_BRA(IA64) @@ -23,8 +30,8 @@ CREATE_BRA(SPARC) #define METHOD_ITEM(n, id, name) \ REGISTER_FILTER_ITEM( \ - CreateBra_Decoder_ ## n, \ - CreateBra_Encoder_ ## n, \ + CreateBra_Decoder_ ## n, GET_CREATE_FUNC( \ + CreateBra_Encoder_ ## n), \ 0x3030000 + id, name) REGISTER_CODECS_VAR @@ -38,4 +45,11 @@ REGISTER_CODECS_VAR REGISTER_CODECS(Branch) +namespace NArm64 { +REGISTER_FILTER_E(ARM64, + CDecoder(), + CEncoder(), + 0xa, "ARM64") +} + }} diff --git a/3rdparty/lzma/CPP/7zip/Compress/ByteSwap.cpp b/3rdparty/lzma/CPP/7zip/Compress/ByteSwap.cpp index 4c11806eb73..cc28d8b90b5 100644 --- a/3rdparty/lzma/CPP/7zip/Compress/ByteSwap.cpp +++ b/3rdparty/lzma/CPP/7zip/Compress/ByteSwap.cpp @@ -2,6 +2,8 @@ #include "StdAfx.h" +#include "../../../C/SwapBytes.h" + #include "../../Common/MyCom.h" #include "../ICoder.h" @@ -11,80 +13,77 @@ namespace NCompress { namespace NByteSwap { -class CByteSwap2: - public ICompressFilter, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP1(ICompressFilter); - INTERFACE_ICompressFilter(;) -}; - -class CByteSwap4: - public ICompressFilter, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP1(ICompressFilter); - INTERFACE_ICompressFilter(;) -}; +Z7_CLASS_IMP_COM_1(CByteSwap2, ICompressFilter) }; +Z7_CLASS_IMP_COM_1(CByteSwap4, ICompressFilter) }; -STDMETHODIMP CByteSwap2::Init() { return S_OK; } +Z7_COM7F_IMF(CByteSwap2::Init()) { return S_OK; } -STDMETHODIMP_(UInt32) CByteSwap2::Filter(Byte *data, UInt32 size) +Z7_COM7F_IMF2(UInt32, CByteSwap2::Filter(Byte *data, UInt32 size)) { - const UInt32 kStep = 2; - if (size < kStep) - return 0; - size &= ~(kStep - 1); - - const Byte *end = data + (size_t)size; - - do + const UInt32 kMask = 2 - 1; + size &= ~kMask; + /* + if ((unsigned)(ptrdiff_t)data & kMask) { - Byte b0 = data[0]; - data[0] = data[1]; - data[1] = b0; - data += kStep; + if (size == 0) + return 0; + const Byte *end = data + (size_t)size; + do + { + const Byte b0 = data[0]; + data[0] = data[1]; + data[1] = b0; + data += kStep; + } + while (data != end); } - while (data != end); - + else + */ + z7_SwapBytes2((UInt16 *)(void *)data, size >> 1); return size; } -STDMETHODIMP CByteSwap4::Init() { return S_OK; } -STDMETHODIMP_(UInt32) CByteSwap4::Filter(Byte *data, UInt32 size) +Z7_COM7F_IMF(CByteSwap4::Init()) { return S_OK; } + +Z7_COM7F_IMF2(UInt32, CByteSwap4::Filter(Byte *data, UInt32 size)) { - const UInt32 kStep = 4; - if (size < kStep) - return 0; - size &= ~(kStep - 1); - - const Byte *end = data + (size_t)size; - - do + const UInt32 kMask = 4 - 1; + size &= ~kMask; + /* + if ((unsigned)(ptrdiff_t)data & kMask) { - Byte b0 = data[0]; - Byte b1 = data[1]; - data[0] = data[3]; - data[1] = data[2]; - data[2] = b1; - data[3] = b0; - data += kStep; + if (size == 0) + return 0; + const Byte *end = data + (size_t)size; + do + { + const Byte b0 = data[0]; + const Byte b1 = data[1]; + data[0] = data[3]; + data[1] = data[2]; + data[2] = b1; + data[3] = b0; + data += kStep; + } + while (data != end); } - while (data != end); - + else + */ + z7_SwapBytes4((UInt32 *)(void *)data, size >> 2); return size; } +static struct C_SwapBytesPrepare { C_SwapBytesPrepare() { z7_SwapBytesPrepare(); } } g_SwapBytesPrepare; + + REGISTER_FILTER_CREATE(CreateFilter2, CByteSwap2()) REGISTER_FILTER_CREATE(CreateFilter4, CByteSwap4()) REGISTER_CODECS_VAR { REGISTER_FILTER_ITEM(CreateFilter2, CreateFilter2, 0x20302, "Swap2"), - REGISTER_FILTER_ITEM(CreateFilter4, CreateFilter4, 0x20304, "Swap4") + REGISTER_FILTER_ITEM(CreateFilter4, CreateFilter4, 0x20304, "Swap4"), }; REGISTER_CODECS(ByteSwap) diff --git a/3rdparty/lzma/CPP/7zip/Compress/CodecExports.cpp b/3rdparty/lzma/CPP/7zip/Compress/CodecExports.cpp index 99085040d07..e37ae143b05 100644 --- a/3rdparty/lzma/CPP/7zip/Compress/CodecExports.cpp +++ b/3rdparty/lzma/CPP/7zip/Compress/CodecExports.cpp @@ -3,11 +3,13 @@ #include "StdAfx.h" #include "../../../C/CpuArch.h" +#include "../../../C/7zVersion.h" #include "../../Common/ComTry.h" #include "../../Common/MyCom.h" #include "../../Windows/Defs.h" +#include "../../Windows/PropVariant.h" #include "../ICoder.h" @@ -21,7 +23,7 @@ extern const CHasherInfo *g_Hashers[]; static void SetPropFromAscii(const char *s, PROPVARIANT *prop) throw() { - UINT len = (UINT)strlen(s); + const UINT len = (UINT)strlen(s); BSTR dest = ::SysAllocStringLen(NULL, len); if (dest) { @@ -45,7 +47,7 @@ static HRESULT MethodToClassID(UInt16 typeId, CMethodId id, PROPVARIANT *value) clsId.Data1 = k_7zip_GUID_Data1; clsId.Data2 = k_7zip_GUID_Data2; clsId.Data3 = typeId; - SetUi64(clsId.Data4, id); + SetUi64(clsId.Data4, id) return SetPropGUID(clsId, value); } @@ -61,7 +63,7 @@ static HRESULT FindCodecClassId(const GUID *clsid, bool isCoder2, bool isFilter, if (clsid->Data3 == k_7zip_GUID_Data3_Decoder) encode = false; else if (clsid->Data3 != k_7zip_GUID_Data3_Encoder) return S_OK; - UInt64 id = GetUi64(clsid->Data4); + const UInt64 id = GetUi64(clsid->Data4); for (unsigned i = 0; i < g_NumCodecs; i++) { @@ -75,13 +77,21 @@ static HRESULT FindCodecClassId(const GUID *clsid, bool isCoder2, bool isFilter, if (codec.NumStreams == 1 ? isCoder2 : !isCoder2) return E_NOINTERFACE; - index = i; + index = (int)i; return S_OK; } return S_OK; } +/* +#ifdef __GNUC__ +#ifndef __clang__ +#pragma GCC diagnostic ignored "-Wduplicated-branches" +#endif +#endif +*/ + static HRESULT CreateCoderMain(unsigned index, bool encode, void **coder) { COM_TRY_BEGIN @@ -97,12 +107,15 @@ static HRESULT CreateCoderMain(unsigned index, bool encode, void **coder) if (c) { IUnknown *unk; + unk = (IUnknown *)c; + /* if (codec.IsFilter) unk = (IUnknown *)(ICompressFilter *)c; else if (codec.NumStreams != 1) unk = (IUnknown *)(ICompressCoder2 *)c; else unk = (IUnknown *)(ICompressCoder *)c; + */ unk->AddRef(); *coder = c; } @@ -136,23 +149,29 @@ static HRESULT CreateCoder2(bool encode, UInt32 index, const GUID *iid, void **o return CreateCoderMain(index, encode, outObject); } + +STDAPI CreateDecoder(UInt32 index, const GUID *iid, void **outObject); STDAPI CreateDecoder(UInt32 index, const GUID *iid, void **outObject) { return CreateCoder2(false, index, iid, outObject); } + +STDAPI CreateEncoder(UInt32 index, const GUID *iid, void **outObject); STDAPI CreateEncoder(UInt32 index, const GUID *iid, void **outObject) { return CreateCoder2(true, index, iid, outObject); } + +STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject); STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject) { *outObject = NULL; bool isFilter = false; bool isCoder2 = false; - bool isCoder = (*iid == IID_ICompressCoder) != 0; + const bool isCoder = (*iid == IID_ICompressCoder) != 0; if (!isCoder) { isFilter = (*iid == IID_ICompressFilter) != 0; @@ -166,15 +185,17 @@ STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject) bool encode; int codecIndex; - HRESULT res = FindCodecClassId(clsid, isCoder2, isFilter, encode, codecIndex); + const HRESULT res = FindCodecClassId(clsid, isCoder2, isFilter, encode, codecIndex); if (res != S_OK) return res; if (codecIndex < 0) return CLASS_E_CLASSNOTAVAILABLE; - return CreateCoderMain(codecIndex, encode, outObject); + return CreateCoderMain((unsigned)codecIndex, encode, outObject); } + +STDAPI GetMethodProperty(UInt32 codecIndex, PROPID propID, PROPVARIANT *value); STDAPI GetMethodProperty(UInt32 codecIndex, PROPID propID, PROPVARIANT *value) { ::VariantClear((VARIANTARG *)value); @@ -211,15 +232,12 @@ STDAPI GetMethodProperty(UInt32 codecIndex, PROPID propID, PROPVARIANT *value) value->ulVal = (ULONG)codec.NumStreams; } break; - /* case NMethodPropID::kIsFilter: - // if (codec.IsFilter) { value->vt = VT_BOOL; value->boolVal = BoolToVARIANT_BOOL(codec.IsFilter); } break; - */ /* case NMethodPropID::kDecoderFlags: { @@ -238,7 +256,9 @@ STDAPI GetMethodProperty(UInt32 codecIndex, PROPID propID, PROPVARIANT *value) return S_OK; } -STDAPI GetNumberOfMethods(UINT32 *numCodecs) + +STDAPI GetNumberOfMethods(UInt32 *numCodecs); +STDAPI GetNumberOfMethods(UInt32 *numCodecs) { *numCodecs = g_NumCodecs; return S_OK; @@ -253,10 +273,10 @@ static int FindHasherClassId(const GUID *clsid) throw() clsid->Data2 != k_7zip_GUID_Data2 || clsid->Data3 != k_7zip_GUID_Data3_Hasher) return -1; - UInt64 id = GetUi64(clsid->Data4); + const UInt64 id = GetUi64(clsid->Data4); for (unsigned i = 0; i < g_NumCodecs; i++) if (id == g_Hashers[i]->Id) - return i; + return (int)i; return -1; } @@ -270,17 +290,19 @@ static HRESULT CreateHasher2(UInt32 index, IHasher **hasher) COM_TRY_END } +STDAPI CreateHasher(const GUID *clsid, IHasher **outObject); STDAPI CreateHasher(const GUID *clsid, IHasher **outObject) { COM_TRY_BEGIN - *outObject = 0; - int index = FindHasherClassId(clsid); + *outObject = NULL; + const int index = FindHasherClassId(clsid); if (index < 0) return CLASS_E_CLASSNOTAVAILABLE; - return CreateHasher2(index, outObject); + return CreateHasher2((UInt32)(unsigned)index, outObject); COM_TRY_END } +STDAPI GetHasherProp(UInt32 codecIndex, PROPID propID, PROPVARIANT *value); STDAPI GetHasherProp(UInt32 codecIndex, PROPID propID, PROPVARIANT *value) { ::VariantClear((VARIANTARG *)value); @@ -306,18 +328,9 @@ STDAPI GetHasherProp(UInt32 codecIndex, PROPID propID, PROPVARIANT *value) return S_OK; } -class CHashers: - public IHashers, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP1(IHashers) - - STDMETHOD_(UInt32, GetNumHashers)(); - STDMETHOD(GetHasherProp)(UInt32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(CreateHasher)(UInt32 index, IHasher **hasher); -}; +Z7_CLASS_IMP_COM_1(CHashers, IHashers) }; +STDAPI GetHashers(IHashers **hashers); STDAPI GetHashers(IHashers **hashers) { COM_TRY_BEGIN @@ -328,17 +341,38 @@ STDAPI GetHashers(IHashers **hashers) COM_TRY_END } -STDMETHODIMP_(UInt32) CHashers::GetNumHashers() +Z7_COM7F_IMF2(UInt32, CHashers::GetNumHashers()) { return g_NumHashers; } -STDMETHODIMP CHashers::GetHasherProp(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHashers::GetHasherProp(UInt32 index, PROPID propID, PROPVARIANT *value)) { return ::GetHasherProp(index, propID, value); } -STDMETHODIMP CHashers::CreateHasher(UInt32 index, IHasher **hasher) +Z7_COM7F_IMF(CHashers::CreateHasher(UInt32 index, IHasher **hasher)) { return ::CreateHasher2(index, hasher); } + + +STDAPI GetModuleProp(PROPID propID, PROPVARIANT *value); +STDAPI GetModuleProp(PROPID propID, PROPVARIANT *value) +{ + ::VariantClear((VARIANTARG *)value); + switch (propID) + { + case NModulePropID::kInterfaceType: + { + NWindows::NCOM::PropVarEm_Set_UInt32(value, NModuleInterfaceType::k_IUnknown_VirtDestructor_ThisModule); + break; + } + case NModulePropID::kVersion: + { + NWindows::NCOM::PropVarEm_Set_UInt32(value, (MY_VER_MAJOR << 16) | MY_VER_MINOR); + break; + } + } + return S_OK; +} diff --git a/3rdparty/lzma/CPP/7zip/Compress/CopyCoder.cpp b/3rdparty/lzma/CPP/7zip/Compress/CopyCoder.cpp index ac6ab2e718a..b779e08b5b3 100644 --- a/3rdparty/lzma/CPP/7zip/Compress/CopyCoder.cpp +++ b/3rdparty/lzma/CPP/7zip/Compress/CopyCoder.cpp @@ -15,10 +15,15 @@ CCopyCoder::~CCopyCoder() ::MidFree(_buf); } -STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream, +Z7_COM7F_IMF(CCopyCoder::SetFinishMode(UInt32 /* finishMode */)) +{ + return S_OK; +} + +Z7_COM7F_IMF(CCopyCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 *outSize, - ICompressProgressInfo *progress) + ICompressProgressInfo *progress)) { if (!_buf) { @@ -32,12 +37,39 @@ STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream, for (;;) { UInt32 size = kBufSize; - if (outSize && size > *outSize - TotalSize) - size = (UInt32)(*outSize - TotalSize); - if (size == 0) - return S_OK; + if (outSize) + { + const UInt64 rem = *outSize - TotalSize; + if (size > rem) + { + size = (UInt32)rem; + if (size == 0) + { + /* if we enable the following check, + we will make one call of Read(_buf, 0) for empty stream */ + // if (TotalSize != 0) + return S_OK; + } + } + } - HRESULT readRes = inStream->Read(_buf, size, &size); + HRESULT readRes; + { + UInt32 pos = 0; + do + { + const UInt32 curSize = size - pos; + UInt32 processed = 0; + readRes = inStream->Read(_buf + pos, curSize, &processed); + if (processed > curSize) + return E_FAIL; // internal code failure + pos += processed; + if (readRes != S_OK || processed == 0) + break; + } + while (pos < kBufSize); + size = pos; + } if (size == 0) return readRes; @@ -47,12 +79,15 @@ STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream, UInt32 pos = 0; do { - UInt32 curSize = size - pos; - HRESULT res = outStream->Write(_buf + pos, curSize, &curSize); - pos += curSize; - TotalSize += curSize; - RINOK(res); - if (curSize == 0) + const UInt32 curSize = size - pos; + UInt32 processed = 0; + const HRESULT res = outStream->Write(_buf + pos, curSize, &processed); + if (processed > curSize) + return E_FAIL; // internal code failure + pos += processed; + TotalSize += processed; + RINOK(res) + if (processed == 0) return E_FAIL; } while (pos < size); @@ -60,29 +95,32 @@ STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream, else TotalSize += size; - RINOK(readRes); + RINOK(readRes) + + if (size != kBufSize) + return S_OK; - if (progress) + if (progress && (TotalSize & (((UInt32)1 << 22) - 1)) == 0) { - RINOK(progress->SetRatioInfo(&TotalSize, &TotalSize)); + RINOK(progress->SetRatioInfo(&TotalSize, &TotalSize)) } } } -STDMETHODIMP CCopyCoder::SetInStream(ISequentialInStream *inStream) +Z7_COM7F_IMF(CCopyCoder::SetInStream(ISequentialInStream *inStream)) { _inStream = inStream; TotalSize = 0; return S_OK; } -STDMETHODIMP CCopyCoder::ReleaseInStream() +Z7_COM7F_IMF(CCopyCoder::ReleaseInStream()) { _inStream.Release(); return S_OK; } -STDMETHODIMP CCopyCoder::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CCopyCoder::Read(void *data, UInt32 size, UInt32 *processedSize)) { UInt32 realProcessedSize = 0; HRESULT res = _inStream->Read(data, size, &realProcessedSize); @@ -92,7 +130,7 @@ STDMETHODIMP CCopyCoder::Read(void *data, UInt32 size, UInt32 *processedSize) return res; } -STDMETHODIMP CCopyCoder::GetInStreamProcessedSize(UInt64 *value) +Z7_COM7F_IMF(CCopyCoder::GetInStreamProcessedSize(UInt64 *value)) { *value = TotalSize; return S_OK; @@ -108,7 +146,7 @@ HRESULT CopyStream_ExactSize(ISequentialInStream *inStream, ISequentialOutStream { NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec; - RINOK(copyCoder->Code(inStream, outStream, NULL, &size, progress)); + RINOK(copyCoder->Code(inStream, outStream, NULL, &size, progress)) return copyCoderSpec->TotalSize == size ? S_OK : E_FAIL; } diff --git a/3rdparty/lzma/CPP/7zip/Compress/CopyCoder.h b/3rdparty/lzma/CPP/7zip/Compress/CopyCoder.h index a21c0988a91..cb93e4eea9f 100644 --- a/3rdparty/lzma/CPP/7zip/Compress/CopyCoder.h +++ b/3rdparty/lzma/CPP/7zip/Compress/CopyCoder.h @@ -1,7 +1,7 @@ // Compress/CopyCoder.h -#ifndef __COMPRESS_COPY_CODER_H -#define __COMPRESS_COPY_CODER_H +#ifndef ZIP7_INC_COMPRESS_COPY_CODER_H +#define ZIP7_INC_COMPRESS_COPY_CODER_H #include "../../Common/MyCom.h" @@ -9,33 +9,21 @@ namespace NCompress { -class CCopyCoder: - public ICompressCoder, - public ICompressSetInStream, - public ISequentialInStream, - public ICompressGetInStreamProcessedSize, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_5( + CCopyCoder + , ICompressCoder + , ICompressSetInStream + , ISequentialInStream + , ICompressSetFinishMode + , ICompressGetInStreamProcessedSize +) Byte *_buf; CMyComPtr<ISequentialInStream> _inStream; public: UInt64 TotalSize; - CCopyCoder(): _buf(0), TotalSize(0) {}; + CCopyCoder(): _buf(NULL), TotalSize(0) {} ~CCopyCoder(); - - MY_UNKNOWN_IMP4( - ICompressCoder, - ICompressSetInStream, - ISequentialInStream, - ICompressGetInStreamProcessedSize) - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(SetInStream)(ISequentialInStream *inStream); - STDMETHOD(ReleaseInStream)(); - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(GetInStreamProcessedSize)(UInt64 *value); }; HRESULT CopyStream(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress); diff --git a/3rdparty/lzma/CPP/7zip/Compress/DeltaFilter.cpp b/3rdparty/lzma/CPP/7zip/Compress/DeltaFilter.cpp index 3986ae4fddb..35b77ba75cd 100644 --- a/3rdparty/lzma/CPP/7zip/Compress/DeltaFilter.cpp +++ b/3rdparty/lzma/CPP/7zip/Compress/DeltaFilter.cpp @@ -23,41 +23,40 @@ struct CDelta }; -#ifndef EXTRACT_ONLY +#ifndef Z7_EXTRACT_ONLY -class CEncoder: +class CEncoder Z7_final: public ICompressFilter, public ICompressSetCoderProperties, public ICompressWriteCoderProperties, - CDelta, - public CMyUnknownImp + public CMyUnknownImp, + CDelta { -public: - MY_UNKNOWN_IMP3(ICompressFilter, ICompressSetCoderProperties, ICompressWriteCoderProperties) - INTERFACE_ICompressFilter(;) - STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); - STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream); + Z7_IFACES_IMP_UNK_3( + ICompressFilter, + ICompressSetCoderProperties, + ICompressWriteCoderProperties) }; -STDMETHODIMP CEncoder::Init() +Z7_COM7F_IMF(CEncoder::Init()) { DeltaInit(); return S_OK; } -STDMETHODIMP_(UInt32) CEncoder::Filter(Byte *data, UInt32 size) +Z7_COM7F_IMF2(UInt32, CEncoder::Filter(Byte *data, UInt32 size)) { Delta_Encode(_state, _delta, data, size); return size; } -STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps) +Z7_COM7F_IMF(CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)) { UInt32 delta = _delta; for (UInt32 i = 0; i < numProps; i++) { const PROPVARIANT &prop = props[i]; - PROPID propID = propIDs[i]; + const PROPID propID = propIDs[i]; if (propID >= NCoderPropID::kReduceSize) continue; if (prop.vt != VT_UI4) @@ -78,40 +77,39 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIA return S_OK; } -STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) +Z7_COM7F_IMF(CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)) { - Byte prop = (Byte)(_delta - 1); + const Byte prop = (Byte)(_delta - 1); return outStream->Write(&prop, 1, NULL); } #endif -class CDecoder: +class CDecoder Z7_final: public ICompressFilter, public ICompressSetDecoderProperties2, - CDelta, - public CMyUnknownImp + public CMyUnknownImp, + CDelta { -public: - MY_UNKNOWN_IMP2(ICompressFilter, ICompressSetDecoderProperties2) - INTERFACE_ICompressFilter(;) - STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); + Z7_IFACES_IMP_UNK_2( + ICompressFilter, + ICompressSetDecoderProperties2) }; -STDMETHODIMP CDecoder::Init() +Z7_COM7F_IMF(CDecoder::Init()) { DeltaInit(); return S_OK; } -STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size) +Z7_COM7F_IMF2(UInt32, CDecoder::Filter(Byte *data, UInt32 size)) { Delta_Decode(_state, _delta, data, size); return size; } -STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *props, UInt32 size) +Z7_COM7F_IMF(CDecoder::SetDecoderProperties2(const Byte *props, UInt32 size)) { if (size != 1) return E_INVALIDARG; diff --git a/3rdparty/lzma/CPP/7zip/Compress/Lzma2Decoder.cpp b/3rdparty/lzma/CPP/7zip/Compress/Lzma2Decoder.cpp index 1a378bbe3a1..eab78000201 100644 --- a/3rdparty/lzma/CPP/7zip/Compress/Lzma2Decoder.cpp +++ b/3rdparty/lzma/CPP/7zip/Compress/Lzma2Decoder.cpp @@ -2,263 +2,264 @@ #include "StdAfx.h" +// #include <stdio.h> + #include "../../../C/Alloc.h" +// #include "../../../C/CpuTicks.h" #include "../Common/StreamUtils.h" #include "Lzma2Decoder.h" -static HRESULT SResToHRESULT(SRes res) -{ - switch (res) - { - case SZ_OK: return S_OK; - case SZ_ERROR_MEM: return E_OUTOFMEMORY; - case SZ_ERROR_PARAM: return E_INVALIDARG; - // case SZ_ERROR_PROGRESS: return E_ABORT; - case SZ_ERROR_DATA: return S_FALSE; - } - return E_FAIL; -} - namespace NCompress { namespace NLzma2 { CDecoder::CDecoder(): - _inBuf(NULL), - _inBufSize(0), - _inBufSizeNew(1 << 20), - _outStepSize(1 << 22), - _outSizeDefined(false), - _finishMode(false) -{ - Lzma2Dec_Construct(&_state); -} - -STDMETHODIMP CDecoder::SetInBufSize(UInt32 , UInt32 size) { _inBufSizeNew = size; return S_OK; } -STDMETHODIMP CDecoder::SetOutBufSize(UInt32 , UInt32 size) { _outStepSize = size; return S_OK; } + _dec(NULL) + , _inProcessed(0) + , _prop(0xFF) + , _finishMode(false) + , _inBufSize(1 << 20) + , _outStep(1 << 20) + #ifndef Z7_ST + , _tryMt(1) + , _numThreads(1) + , _memUsage((UInt64)(sizeof(size_t)) << 28) + #endif +{} CDecoder::~CDecoder() { - Lzma2Dec_Free(&_state, &g_Alloc); - MidFree(_inBuf); + if (_dec) + Lzma2DecMt_Destroy(_dec); } -STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *prop, UInt32 size) +Z7_COM7F_IMF(CDecoder::SetInBufSize(UInt32 , UInt32 size)) { _inBufSize = size; return S_OK; } +Z7_COM7F_IMF(CDecoder::SetOutBufSize(UInt32 , UInt32 size)) { _outStep = size; return S_OK; } + +Z7_COM7F_IMF(CDecoder::SetDecoderProperties2(const Byte *prop, UInt32 size)) { if (size != 1) return E_NOTIMPL; - - RINOK(SResToHRESULT(Lzma2Dec_Allocate(&_state, prop[0], &g_Alloc))); - if (!_inBuf || _inBufSize != _inBufSizeNew) - { - MidFree(_inBuf); - _inBufSize = 0; - _inBuf = (Byte *)MidAlloc(_inBufSizeNew); - if (!_inBuf) - return E_OUTOFMEMORY; - _inBufSize = _inBufSizeNew; - } - + if (prop[0] > 40) + return E_NOTIMPL; + _prop = prop[0]; return S_OK; } -STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value) { *value = _inSizeProcessed; return S_OK; } -STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) { _inStream = inStream; return S_OK; } -STDMETHODIMP CDecoder::ReleaseInStream() { _inStream.Release(); return S_OK; } -STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize) +Z7_COM7F_IMF(CDecoder::SetFinishMode(UInt32 finishMode)) { - _outSizeDefined = (outSize != NULL); - _outSize = 0; - if (_outSizeDefined) - _outSize = *outSize; - - Lzma2Dec_Init(&_state); - - _inPos = _inSize = 0; - _inSizeProcessed = _outSizeProcessed = 0; + _finishMode = (finishMode != 0); return S_OK; } -STDMETHODIMP CDecoder::SetFinishMode(UInt32 finishMode) + + +#ifndef Z7_ST + +static UInt64 Get_ExpectedBlockSize_From_Dict(UInt32 dictSize) { - _finishMode = (finishMode != 0); - return S_OK; + const UInt32 kMinSize = (UInt32)1 << 20; + const UInt32 kMaxSize = (UInt32)1 << 28; + UInt64 blockSize = (UInt64)dictSize << 2; + if (blockSize < kMinSize) blockSize = kMinSize; + if (blockSize > kMaxSize) blockSize = kMaxSize; + if (blockSize < dictSize) blockSize = dictSize; + blockSize += (kMinSize - 1); + blockSize &= ~(UInt64)(kMinSize - 1); + return blockSize; } -STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UInt64 *inSize, - const UInt64 *outSize, ICompressProgressInfo *progress) +#define LZMA2_DIC_SIZE_FROM_PROP_FULL(p) ((p) == 40 ? 0xFFFFFFFF : (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11))) + +#endif + +#define RET_IF_WRAP_ERROR_CONFIRMED(wrapRes, sRes, sResErrorCode) \ + if (wrapRes != S_OK && sRes == sResErrorCode) return wrapRes; + +#define RET_IF_WRAP_ERROR(wrapRes, sRes, sResErrorCode) \ + if (wrapRes != S_OK /* && (sRes == SZ_OK || sRes == sResErrorCode) */) return wrapRes; + +Z7_COM7F_IMF(CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)) { - if (!_inBuf) - return S_FALSE; - SetOutStreamSize(outSize); - - UInt32 step = _outStepSize; - const UInt32 kOutStepSize_Min = 1 << 12; - if (step < kOutStepSize_Min) - step = kOutStepSize_Min; - - SizeT wrPos = _state.decoder.dicPos; + _inProcessed = 0; - SizeT next = (_state.decoder.dicBufSize - _state.decoder.dicPos < step) ? - _state.decoder.dicBufSize : - _state.decoder.dicPos + step; + if (!_dec) + { + _dec = Lzma2DecMt_Create( + // &g_AlignedAlloc, + &g_Alloc, + &g_MidAlloc); + if (!_dec) + return E_OUTOFMEMORY; + } - HRESULT hres = S_OK; + CLzma2DecMtProps props; + Lzma2DecMtProps_Init(&props); - for (;;) + props.inBufSize_ST = _inBufSize; + props.outStep_ST = _outStep; + + #ifndef Z7_ST { - if (_inPos == _inSize) - { - _inPos = _inSize = 0; - hres = inStream->Read(_inBuf, _inBufSize, &_inSize); - if (hres != S_OK) - break; - } + props.numThreads = 1; + UInt32 numThreads = _numThreads; - SizeT dicPos = _state.decoder.dicPos; - SizeT curSize = next - dicPos; - - ELzmaFinishMode finishMode = LZMA_FINISH_ANY; - if (_outSizeDefined) + if (_tryMt && numThreads >= 1) { - const UInt64 rem = _outSize - _outSizeProcessed; - if (curSize >= rem) + const UInt64 useLimit = _memUsage; + const UInt32 dictSize = LZMA2_DIC_SIZE_FROM_PROP_FULL(_prop); + const UInt64 expectedBlockSize64 = Get_ExpectedBlockSize_From_Dict(dictSize); + const size_t expectedBlockSize = (size_t)expectedBlockSize64; + const size_t inBlockMax = expectedBlockSize + expectedBlockSize / 16; + if (expectedBlockSize == expectedBlockSize64 && inBlockMax >= expectedBlockSize) { - curSize = (SizeT)rem; - if (_finishMode) - finishMode = LZMA_FINISH_END; + props.outBlockMax = expectedBlockSize; + props.inBlockMax = inBlockMax; + const size_t kOverheadSize = props.inBufSize_MT + (1 << 16); + const UInt64 okThreads = useLimit / (props.outBlockMax + props.inBlockMax + kOverheadSize); + if (numThreads > okThreads) + numThreads = (UInt32)okThreads; + if (numThreads == 0) + numThreads = 1; + props.numThreads = numThreads; } } + } + #endif - SizeT inSizeProcessed = _inSize - _inPos; - ELzmaStatus status; - SRes res = Lzma2Dec_DecodeToDic(&_state, dicPos + curSize, _inBuf + _inPos, &inSizeProcessed, finishMode, &status); + CSeqInStreamWrap inWrap; + CSeqOutStreamWrap outWrap; + CCompressProgressWrap progressWrap; - _inPos += (UInt32)inSizeProcessed; - _inSizeProcessed += inSizeProcessed; - SizeT outSizeProcessed = _state.decoder.dicPos - dicPos; - _outSizeProcessed += outSizeProcessed; + inWrap.Init(inStream); + outWrap.Init(outStream); + progressWrap.Init(progress); - bool finished = (inSizeProcessed == 0 && outSizeProcessed == 0 - || status == LZMA_STATUS_FINISHED_WITH_MARK); - bool outFinished = (_outSizeDefined && _outSizeProcessed >= _outSize); + SRes res; - if (res != 0 - || _state.decoder.dicPos >= next - || finished - || outFinished) - { - HRESULT res2 = WriteStream(outStream, _state.decoder.dic + wrPos, _state.decoder.dicPos - wrPos); + UInt64 inProcessed = 0; + int isMT = False; - if (_state.decoder.dicPos == _state.decoder.dicBufSize) - _state.decoder.dicPos = 0; - - wrPos = _state.decoder.dicPos; + #ifndef Z7_ST + isMT = _tryMt; + #endif - next = (_state.decoder.dicBufSize - _state.decoder.dicPos < step) ? - _state.decoder.dicBufSize : - _state.decoder.dicPos + step; + // UInt64 cpuTicks = GetCpuTicks(); - if (res != 0) - return S_FALSE; - RINOK(res2); + res = Lzma2DecMt_Decode(_dec, _prop, &props, + &outWrap.vt, outSize, _finishMode, + &inWrap.vt, + &inProcessed, + &isMT, + progress ? &progressWrap.vt : NULL); - if (finished) - { - if (status == LZMA_STATUS_FINISHED_WITH_MARK) - { - if (_finishMode && inSize && *inSize != _inSizeProcessed) - return S_FALSE; - if (finishMode == LZMA_FINISH_END && !outFinished) - return S_FALSE; - return S_OK; - } - return (finishMode == LZMA_FINISH_END) ? S_FALSE : S_OK; - } + /* + cpuTicks = GetCpuTicks() - cpuTicks; + printf("\n ticks = %10I64u\n", cpuTicks / 1000000); + */ - if (outFinished && finishMode == LZMA_FINISH_ANY) - return S_OK; - } - - if (progress) - { - RINOK(progress->SetRatioInfo(&_inSizeProcessed, &_outSizeProcessed)); - } + + #ifndef Z7_ST + /* we reset _tryMt, only if p->props.numThreads was changed */ + if (props.numThreads > 1) + _tryMt = isMT; + #endif + + _inProcessed = inProcessed; + + RET_IF_WRAP_ERROR(progressWrap.Res, res, SZ_ERROR_PROGRESS) + RET_IF_WRAP_ERROR(outWrap.Res, res, SZ_ERROR_WRITE) + RET_IF_WRAP_ERROR_CONFIRMED(inWrap.Res, res, SZ_ERROR_READ) + + if (res == SZ_OK && _finishMode) + { + if (inSize && *inSize != inProcessed) + res = SZ_ERROR_DATA; + if (outSize && *outSize != outWrap.Processed) + res = SZ_ERROR_DATA; } - HRESULT res2 = WriteStream(outStream, _state.decoder.dic + wrPos, _state.decoder.dicPos - wrPos); - if (hres != S_OK) - return hres; - return res2; + return SResToHRESULT(res); } -#ifndef NO_READ_FROM_CODER -STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CDecoder::GetInStreamProcessedSize(UInt64 *value)) { - UInt32 totalProcessed = 0; + *value = _inProcessed; + return S_OK; +} + + +#ifndef Z7_ST + +Z7_COM7F_IMF(CDecoder::SetNumberOfThreads(UInt32 numThreads)) +{ + _numThreads = numThreads; + return S_OK; +} + +Z7_COM7F_IMF(CDecoder::SetMemLimit(UInt64 memUsage)) +{ + _memUsage = memUsage; + return S_OK; +} + +#endif + + +#ifndef Z7_NO_READ_FROM_CODER + +Z7_COM7F_IMF(CDecoder::SetOutStreamSize(const UInt64 *outSize)) +{ + CLzma2DecMtProps props; + Lzma2DecMtProps_Init(&props); + props.inBufSize_ST = _inBufSize; + props.outStep_ST = _outStep; + + _inProcessed = 0; + + if (!_dec) + { + _dec = Lzma2DecMt_Create(&g_AlignedAlloc, &g_MidAlloc); + if (!_dec) + return E_OUTOFMEMORY; + } + + _inWrap.Init(_inStream); + const SRes res = Lzma2DecMt_Init(_dec, _prop, &props, outSize, _finishMode, &_inWrap.vt); + + if (res != SZ_OK) + return SResToHRESULT(res); + return S_OK; +} + + +Z7_COM7F_IMF(CDecoder::SetInStream(ISequentialInStream *inStream)) + { _inStream = inStream; return S_OK; } +Z7_COM7F_IMF(CDecoder::ReleaseInStream()) + { _inStream.Release(); return S_OK; } + + +Z7_COM7F_IMF(CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ if (processedSize) *processedSize = 0; - for (;;) - { - if (_inPos == _inSize) - { - _inPos = _inSize = 0; - RINOK(_inStream->Read(_inBuf, _inBufSize, &_inSize)); - } - { - ELzmaFinishMode finishMode = LZMA_FINISH_ANY; - if (_outSizeDefined) - { - const UInt64 rem = _outSize - _outSizeProcessed; - if (rem <= size) - { - size = (UInt32)rem; - if (_finishMode) - finishMode = LZMA_FINISH_END; - } - } + size_t size2 = size; + UInt64 inProcessed = 0; - SizeT outProcessed = size; - SizeT inProcessed = _inSize - _inPos; - - ELzmaStatus status; - SRes res = Lzma2Dec_DecodeToBuf(&_state, (Byte *)data, &outProcessed, - _inBuf + _inPos, &inProcessed, finishMode, &status); - - _inPos += (UInt32)inProcessed; - _inSizeProcessed += inProcessed; - _outSizeProcessed += outProcessed; - size -= (UInt32)outProcessed; - data = (Byte *)data + outProcessed; - - totalProcessed += (UInt32)outProcessed; - if (processedSize) - *processedSize = totalProcessed; - - if (res != SZ_OK) - { - if (totalProcessed != 0) - return S_OK; - return SResToHRESULT(res); - } - - if (inProcessed == 0 && outProcessed == 0) - return S_OK; - if (status == LZMA_STATUS_FINISHED_WITH_MARK) - return S_OK; - if (outProcessed != 0) - { - if (finishMode != LZMA_FINISH_END || _outSize != _outSizeProcessed) - return S_OK; - } - } - } + const SRes res = Lzma2DecMt_Read(_dec, (Byte *)data, &size2, &inProcessed); + + _inProcessed += inProcessed; + if (processedSize) + *processedSize = (UInt32)size2; + if (res != SZ_OK) + return SResToHRESULT(res); + return S_OK; } #endif diff --git a/3rdparty/lzma/CPP/7zip/Compress/Lzma2Decoder.h b/3rdparty/lzma/CPP/7zip/Compress/Lzma2Decoder.h index a87912fb596..7ca717e7f41 100644 --- a/3rdparty/lzma/CPP/7zip/Compress/Lzma2Decoder.h +++ b/3rdparty/lzma/CPP/7zip/Compress/Lzma2Decoder.h @@ -1,86 +1,85 @@ // Lzma2Decoder.h -#ifndef __LZMA2_DECODER_H -#define __LZMA2_DECODER_H +#ifndef ZIP7_INC_LZMA2_DECODER_H +#define ZIP7_INC_LZMA2_DECODER_H -#include "../../../C/Lzma2Dec.h" +#include "../../../C/Lzma2DecMt.h" -#include "../../Common/MyCom.h" - -#include "../ICoder.h" +#include "../Common/CWrappers.h" namespace NCompress { namespace NLzma2 { -class CDecoder: +class CDecoder Z7_final: public ICompressCoder, public ICompressSetDecoderProperties2, public ICompressSetFinishMode, public ICompressGetInStreamProcessedSize, public ICompressSetBufSize, - #ifndef NO_READ_FROM_CODER + #ifndef Z7_NO_READ_FROM_CODER public ICompressSetInStream, public ICompressSetOutStreamSize, public ISequentialInStream, - #endif + #endif + #ifndef Z7_ST + public ICompressSetCoderMt, + public ICompressSetMemLimit, + #endif public CMyUnknownImp { - CMyComPtr<ISequentialInStream> _inStream; - Byte *_inBuf; - UInt32 _inPos; - UInt32 _inSize; - - bool _finishMode; - bool _outSizeDefined; - UInt64 _outSize; - - UInt64 _inSizeProcessed; - UInt64 _outSizeProcessed; - + Z7_COM_QI_BEGIN2(ICompressCoder) + Z7_COM_QI_ENTRY(ICompressSetDecoderProperties2) + Z7_COM_QI_ENTRY(ICompressSetFinishMode) + Z7_COM_QI_ENTRY(ICompressGetInStreamProcessedSize) + Z7_COM_QI_ENTRY(ICompressSetBufSize) + #ifndef Z7_NO_READ_FROM_CODER + Z7_COM_QI_ENTRY(ICompressSetInStream) + Z7_COM_QI_ENTRY(ICompressSetOutStreamSize) + Z7_COM_QI_ENTRY(ISequentialInStream) + #endif + #ifndef Z7_ST + Z7_COM_QI_ENTRY(ICompressSetCoderMt) + Z7_COM_QI_ENTRY(ICompressSetMemLimit) + #endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(ICompressCoder) + Z7_IFACE_COM7_IMP(ICompressSetDecoderProperties2) + Z7_IFACE_COM7_IMP(ICompressSetFinishMode) + Z7_IFACE_COM7_IMP(ICompressGetInStreamProcessedSize) + Z7_IFACE_COM7_IMP(ICompressSetBufSize) + #ifndef Z7_NO_READ_FROM_CODER + Z7_IFACE_COM7_IMP(ICompressSetOutStreamSize) + Z7_IFACE_COM7_IMP(ICompressSetInStream) + Z7_IFACE_COM7_IMP(ISequentialInStream) + #endif + #ifndef Z7_ST + Z7_IFACE_COM7_IMP(ICompressSetCoderMt) + Z7_IFACE_COM7_IMP(ICompressSetMemLimit) + #endif + + CLzma2DecMtHandle _dec; + UInt64 _inProcessed; + Byte _prop; + int _finishMode; UInt32 _inBufSize; - UInt32 _inBufSizeNew; - UInt32 _outStepSize; - - CLzma2Dec _state; -public: - - MY_QUERYINTERFACE_BEGIN2(ICompressCoder) - MY_QUERYINTERFACE_ENTRY(ICompressSetDecoderProperties2) - MY_QUERYINTERFACE_ENTRY(ICompressSetFinishMode) - MY_QUERYINTERFACE_ENTRY(ICompressGetInStreamProcessedSize) - MY_QUERYINTERFACE_ENTRY(ICompressSetBufSize) - #ifndef NO_READ_FROM_CODER - MY_QUERYINTERFACE_ENTRY(ICompressSetInStream) - MY_QUERYINTERFACE_ENTRY(ICompressSetOutStreamSize) - MY_QUERYINTERFACE_ENTRY(ISequentialInStream) - #endif - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); + UInt32 _outStep; - STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); + #ifndef Z7_ST + int _tryMt; + UInt32 _numThreads; + UInt64 _memUsage; + #endif - STDMETHOD(SetFinishMode)(UInt32 finishMode); - - STDMETHOD(GetInStreamProcessedSize)(UInt64 *value); - - STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size); - STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size); - - STDMETHOD(SetInStream)(ISequentialInStream *inStream); - STDMETHOD(ReleaseInStream)(); - - STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); - - #ifndef NO_READ_FROM_CODER - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - #endif + #ifndef Z7_NO_READ_FROM_CODER + CMyComPtr<ISequentialInStream> _inStream; + CSeqInStreamWrap _inWrap; + #endif +public: CDecoder(); - virtual ~CDecoder(); - + ~CDecoder(); }; }} diff --git a/3rdparty/lzma/CPP/7zip/Compress/Lzma2Encoder.cpp b/3rdparty/lzma/CPP/7zip/Compress/Lzma2Encoder.cpp index 06a11f10eae..0dc7e23b463 100644 --- a/3rdparty/lzma/CPP/7zip/Compress/Lzma2Encoder.cpp +++ b/3rdparty/lzma/CPP/7zip/Compress/Lzma2Encoder.cpp @@ -21,18 +21,20 @@ namespace NLzma2 { CEncoder::CEncoder() { - _encoder = 0; - _encoder = Lzma2Enc_Create(&g_Alloc, &g_BigAlloc); - if (_encoder == 0) + _encoder = NULL; + _encoder = Lzma2Enc_Create(&g_AlignedAlloc, &g_BigAlloc); + if (!_encoder) throw 1; } CEncoder::~CEncoder() { - if (_encoder != 0) + if (_encoder) Lzma2Enc_Destroy(_encoder); } + +HRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzma2Props); HRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzma2Props) { switch (propID) @@ -42,57 +44,82 @@ HRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzm if (prop.vt == VT_UI4) lzma2Props.blockSize = prop.ulVal; else if (prop.vt == VT_UI8) - { - size_t v = (size_t)prop.uhVal.QuadPart; - if (v != prop.uhVal.QuadPart) - return E_INVALIDARG; - lzma2Props.blockSize = v; - } + lzma2Props.blockSize = prop.uhVal.QuadPart; else return E_INVALIDARG; break; } case NCoderPropID::kNumThreads: - if (prop.vt != VT_UI4) return E_INVALIDARG; lzma2Props.numTotalThreads = (int)(prop.ulVal); break; + if (prop.vt != VT_UI4) + return E_INVALIDARG; + lzma2Props.numTotalThreads = (int)(prop.ulVal); + break; default: - RINOK(NLzma::SetLzmaProp(propID, prop, lzma2Props.lzmaProps)); + RINOK(NLzma::SetLzmaProp(propID, prop, lzma2Props.lzmaProps)) } return S_OK; } -STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, - const PROPVARIANT *coderProps, UInt32 numProps) + +Z7_COM7F_IMF(CEncoder::SetCoderProperties(const PROPID *propIDs, + const PROPVARIANT *coderProps, UInt32 numProps)) { CLzma2EncProps lzma2Props; Lzma2EncProps_Init(&lzma2Props); for (UInt32 i = 0; i < numProps; i++) { - RINOK(SetLzma2Prop(propIDs[i], coderProps[i], lzma2Props)); + RINOK(SetLzma2Prop(propIDs[i], coderProps[i], lzma2Props)) } return SResToHRESULT(Lzma2Enc_SetProps(_encoder, &lzma2Props)); } -STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) + +Z7_COM7F_IMF(CEncoder::SetCoderPropertiesOpt(const PROPID *propIDs, + const PROPVARIANT *coderProps, UInt32 numProps)) { - Byte prop = Lzma2Enc_WriteProperties(_encoder); + for (UInt32 i = 0; i < numProps; i++) + { + const PROPVARIANT &prop = coderProps[i]; + const PROPID propID = propIDs[i]; + if (propID == NCoderPropID::kExpectedDataSize) + if (prop.vt == VT_UI8) + Lzma2Enc_SetDataSize(_encoder, prop.uhVal.QuadPart); + } + return S_OK; +} + + +Z7_COM7F_IMF(CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)) +{ + const Byte prop = Lzma2Enc_WriteProperties(_encoder); return WriteStream(outStream, &prop, 1); } -STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress) + +#define RET_IF_WRAP_ERROR(wrapRes, sRes, sResErrorCode) \ + if (wrapRes != S_OK /* && (sRes == SZ_OK || sRes == sResErrorCode) */) return wrapRes; + +Z7_COM7F_IMF(CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)) { - CSeqInStreamWrap inWrap(inStream); - CSeqOutStreamWrap outWrap(outStream); - CCompressProgressWrap progressWrap(progress); - - SRes res = Lzma2Enc_Encode(_encoder, &outWrap.p, &inWrap.p, progress ? &progressWrap.p : NULL); - if (res == SZ_ERROR_READ && inWrap.Res != S_OK) - return inWrap.Res; - if (res == SZ_ERROR_WRITE && outWrap.Res != S_OK) - return outWrap.Res; - if (res == SZ_ERROR_PROGRESS && progressWrap.Res != S_OK) - return progressWrap.Res; + CSeqInStreamWrap inWrap; + CSeqOutStreamWrap outWrap; + CCompressProgressWrap progressWrap; + + inWrap.Init(inStream); + outWrap.Init(outStream); + progressWrap.Init(progress); + + SRes res = Lzma2Enc_Encode2(_encoder, + &outWrap.vt, NULL, NULL, + &inWrap.vt, NULL, 0, + progress ? &progressWrap.vt : NULL); + + RET_IF_WRAP_ERROR(inWrap.Res, res, SZ_ERROR_READ) + RET_IF_WRAP_ERROR(outWrap.Res, res, SZ_ERROR_WRITE) + RET_IF_WRAP_ERROR(progressWrap.Res, res, SZ_ERROR_PROGRESS) + return SResToHRESULT(res); } diff --git a/3rdparty/lzma/CPP/7zip/Compress/Lzma2Encoder.h b/3rdparty/lzma/CPP/7zip/Compress/Lzma2Encoder.h index 8ff6e838351..18c29e1207e 100644 --- a/3rdparty/lzma/CPP/7zip/Compress/Lzma2Encoder.h +++ b/3rdparty/lzma/CPP/7zip/Compress/Lzma2Encoder.h @@ -1,7 +1,7 @@ // Lzma2Encoder.h -#ifndef __LZMA2_ENCODER_H -#define __LZMA2_ENCODER_H +#ifndef ZIP7_INC_LZMA2_ENCODER_H +#define ZIP7_INC_LZMA2_ENCODER_H #include "../../../C/Lzma2Enc.h" @@ -12,23 +12,17 @@ namespace NCompress { namespace NLzma2 { -class CEncoder: - public ICompressCoder, - public ICompressSetCoderProperties, - public ICompressWriteCoderProperties, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_4( + CEncoder + , ICompressCoder + , ICompressSetCoderProperties + , ICompressWriteCoderProperties + , ICompressSetCoderPropertiesOpt +) CLzma2EncHandle _encoder; public: - MY_UNKNOWN_IMP3(ICompressCoder, ICompressSetCoderProperties, ICompressWriteCoderProperties) - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); - STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream); - CEncoder(); - virtual ~CEncoder(); + ~CEncoder(); }; }} diff --git a/3rdparty/lzma/CPP/7zip/Compress/Lzma2Register.cpp b/3rdparty/lzma/CPP/7zip/Compress/Lzma2Register.cpp index 8f279ebf166..fe53346385d 100644 --- a/3rdparty/lzma/CPP/7zip/Compress/Lzma2Register.cpp +++ b/3rdparty/lzma/CPP/7zip/Compress/Lzma2Register.cpp @@ -6,7 +6,7 @@ #include "Lzma2Decoder.h" -#ifndef EXTRACT_ONLY +#ifndef Z7_EXTRACT_ONLY #include "Lzma2Encoder.h" #endif diff --git a/3rdparty/lzma/CPP/7zip/Compress/LzmaDecoder.cpp b/3rdparty/lzma/CPP/7zip/Compress/LzmaDecoder.cpp index 9002678ae08..4f05b4833b6 100644 --- a/3rdparty/lzma/CPP/7zip/Compress/LzmaDecoder.cpp +++ b/3rdparty/lzma/CPP/7zip/Compress/LzmaDecoder.cpp @@ -24,243 +24,324 @@ static HRESULT SResToHRESULT(SRes res) namespace NCompress { namespace NLzma { -CDecoder::CDecoder(): _inBuf(0), _propsWereSet(false), _outSizeDefined(false), - _inBufSize(1 << 20), - _outBufSize(1 << 22), +CDecoder::CDecoder(): FinishStream(false), - NeedMoreInput(false) + _propsWereSet(false), + _outSizeDefined(false), + _outStep(1 << 20), + _inBufSize(0), + _inBufSizeNew(1 << 20), + _lzmaStatus(LZMA_STATUS_NOT_SPECIFIED), + _inBuf(NULL) { - _inSizeProcessed = 0; - _inPos = _inSize = 0; - LzmaDec_Construct(&_state); + _inProcessed = 0; + _inPos = _inLim = 0; + + /* + AlignOffsetAlloc_CreateVTable(&_alloc); + _alloc.numAlignBits = 7; + _alloc.offset = 0; + */ + LzmaDec_CONSTRUCT(&_state) } CDecoder::~CDecoder() { - LzmaDec_Free(&_state, &g_Alloc); + LzmaDec_Free(&_state, &g_AlignedAlloc); // &_alloc.vt MyFree(_inBuf); } -STDMETHODIMP CDecoder::SetInBufSize(UInt32 , UInt32 size) { _inBufSize = size; return S_OK; } -STDMETHODIMP CDecoder::SetOutBufSize(UInt32 , UInt32 size) { _outBufSize = size; return S_OK; } +Z7_COM7F_IMF(CDecoder::SetInBufSize(UInt32 , UInt32 size)) + { _inBufSizeNew = size; return S_OK; } +Z7_COM7F_IMF(CDecoder::SetOutBufSize(UInt32 , UInt32 size)) + { _outStep = size; return S_OK; } HRESULT CDecoder::CreateInputBuffer() { - if (_inBuf == 0 || _inBufSize != _inBufSizeAllocated) + if (!_inBuf || _inBufSizeNew != _inBufSize) { MyFree(_inBuf); - _inBuf = (Byte *)MyAlloc(_inBufSize); - if (_inBuf == 0) + _inBufSize = 0; + _inBuf = (Byte *)MyAlloc(_inBufSizeNew); + if (!_inBuf) return E_OUTOFMEMORY; - _inBufSizeAllocated = _inBufSize; + _inBufSize = _inBufSizeNew; } return S_OK; } -STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *prop, UInt32 size) + +Z7_COM7F_IMF(CDecoder::SetDecoderProperties2(const Byte *prop, UInt32 size)) { - RINOK(SResToHRESULT(LzmaDec_Allocate(&_state, prop, size, &g_Alloc))); + RINOK(SResToHRESULT(LzmaDec_Allocate(&_state, prop, size, &g_AlignedAlloc))) // &_alloc.vt _propsWereSet = true; return CreateInputBuffer(); } + void CDecoder::SetOutStreamSizeResume(const UInt64 *outSize) { _outSizeDefined = (outSize != NULL); + _outSize = 0; if (_outSizeDefined) _outSize = *outSize; - _outSizeProcessed = 0; - _wrPos = 0; + _outProcessed = 0; + _lzmaStatus = LZMA_STATUS_NOT_SPECIFIED; + LzmaDec_Init(&_state); } -STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize) + +Z7_COM7F_IMF(CDecoder::SetOutStreamSize(const UInt64 *outSize)) { - _inSizeProcessed = 0; - _inPos = _inSize = 0; - NeedMoreInput = false; + _inProcessed = 0; + _inPos = _inLim = 0; SetOutStreamSizeResume(outSize); return S_OK; } -STDMETHODIMP CDecoder::SetFinishMode(UInt32 finishMode) + +Z7_COM7F_IMF(CDecoder::SetFinishMode(UInt32 finishMode)) { FinishStream = (finishMode != 0); return S_OK; } + +Z7_COM7F_IMF(CDecoder::GetInStreamProcessedSize(UInt64 *value)) +{ + *value = _inProcessed; + return S_OK; +} + + HRESULT CDecoder::CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress) { - if (_inBuf == 0 || !_propsWereSet) + if (!_inBuf || !_propsWereSet) return S_FALSE; + + const UInt64 startInProgress = _inProcessed; + SizeT wrPos = _state.dicPos; + HRESULT readRes = S_OK; - UInt64 startInProgress = _inSizeProcessed; - - SizeT next = (_state.dicBufSize - _state.dicPos < _outBufSize) ? _state.dicBufSize : (_state.dicPos + _outBufSize); for (;;) { - if (_inPos == _inSize) + if (_inPos == _inLim && readRes == S_OK) { - _inPos = _inSize = 0; - RINOK(inStream->Read(_inBuf, _inBufSizeAllocated, &_inSize)); + _inPos = _inLim = 0; + readRes = inStream->Read(_inBuf, _inBufSize, &_inLim); + } + + const SizeT dicPos = _state.dicPos; + SizeT size; + { + SizeT next = _state.dicBufSize; + if (next - wrPos > _outStep) + next = wrPos + _outStep; + size = next - dicPos; } - SizeT dicPos = _state.dicPos; - SizeT curSize = next - dicPos; - ELzmaFinishMode finishMode = LZMA_FINISH_ANY; if (_outSizeDefined) { - const UInt64 rem = _outSize - _outSizeProcessed; - if (rem <= curSize) + const UInt64 rem = _outSize - _outProcessed; + if (size >= rem) { - curSize = (SizeT)rem; + size = (SizeT)rem; if (FinishStream) finishMode = LZMA_FINISH_END; } } - SizeT inSizeProcessed = _inSize - _inPos; + SizeT inProcessed = _inLim - _inPos; ELzmaStatus status; - SRes res = LzmaDec_DecodeToDic(&_state, dicPos + curSize, _inBuf + _inPos, &inSizeProcessed, finishMode, &status); - _inPos += (UInt32)inSizeProcessed; - _inSizeProcessed += inSizeProcessed; - SizeT outSizeProcessed = _state.dicPos - dicPos; - _outSizeProcessed += outSizeProcessed; + const SRes res = LzmaDec_DecodeToDic(&_state, dicPos + size, _inBuf + _inPos, &inProcessed, finishMode, &status); + + _lzmaStatus = status; + _inPos += (UInt32)inProcessed; + _inProcessed += inProcessed; + const SizeT outProcessed = _state.dicPos - dicPos; + _outProcessed += outProcessed; - bool finished = (inSizeProcessed == 0 && outSizeProcessed == 0); - bool stopDecoding = (_outSizeDefined && _outSizeProcessed >= _outSize); + // we check for LZMA_STATUS_NEEDS_MORE_INPUT to allow RangeCoder initialization, if (_outSizeDefined && _outSize == 0) + const bool outFinished = (_outSizeDefined && _outProcessed >= _outSize); - if (res != 0 || _state.dicPos == next || finished || stopDecoding) + const bool needStop = (res != 0 + || (inProcessed == 0 && outProcessed == 0) + || status == LZMA_STATUS_FINISHED_WITH_MARK + || (outFinished && status != LZMA_STATUS_NEEDS_MORE_INPUT)); + + if (needStop || outProcessed >= size) { - HRESULT res2 = WriteStream(outStream, _state.dic + _wrPos, _state.dicPos - _wrPos); + const HRESULT res2 = WriteStream(outStream, _state.dic + wrPos, _state.dicPos - wrPos); - _wrPos = _state.dicPos; if (_state.dicPos == _state.dicBufSize) - { _state.dicPos = 0; - _wrPos = 0; - } - next = (_state.dicBufSize - _state.dicPos < _outBufSize) ? _state.dicBufSize : (_state.dicPos + _outBufSize); + wrPos = _state.dicPos; + + RINOK(res2) - if (res != 0) - return S_FALSE; - RINOK(res2); - if (stopDecoding) + if (needStop) { - if (status == LZMA_STATUS_NEEDS_MORE_INPUT) - NeedMoreInput = true; - if (FinishStream && - status != LZMA_STATUS_FINISHED_WITH_MARK && - status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) + if (res != 0) + { + // return SResToHRESULT(res); return S_FALSE; - return S_OK; - } - if (finished) - { - if (status == LZMA_STATUS_NEEDS_MORE_INPUT) - NeedMoreInput = true; - return (status == LZMA_STATUS_FINISHED_WITH_MARK ? S_OK : S_FALSE); + } + + if (status == LZMA_STATUS_FINISHED_WITH_MARK) + { + if (FinishStream) + if (_outSizeDefined && _outSize != _outProcessed) + return S_FALSE; + return readRes; + } + + if (outFinished && status != LZMA_STATUS_NEEDS_MORE_INPUT) + if (!FinishStream || status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) + return readRes; + + return S_FALSE; } } + if (progress) { - UInt64 inSize = _inSizeProcessed - startInProgress; - RINOK(progress->SetRatioInfo(&inSize, &_outSizeProcessed)); + const UInt64 inSize = _inProcessed - startInProgress; + RINOK(progress->SetRatioInfo(&inSize, &_outProcessed)) } } } -STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress) + +Z7_COM7F_IMF(CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)) { - if (_inBuf == 0) + if (!_inBuf) return E_INVALIDARG; SetOutStreamSize(outSize); - return CodeSpec(inStream, outStream, progress); + HRESULT res = CodeSpec(inStream, outStream, progress); + if (res == S_OK) + if (FinishStream && inSize && *inSize != _inProcessed) + res = S_FALSE; + return res; } -#ifndef NO_READ_FROM_CODER -STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) { _inStream = inStream; return S_OK; } -STDMETHODIMP CDecoder::ReleaseInStream() { _inStream.Release(); return S_OK; } +#ifndef Z7_NO_READ_FROM_CODER -STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CDecoder::SetInStream(ISequentialInStream *inStream)) + { _inStream = inStream; return S_OK; } +Z7_COM7F_IMF(CDecoder::ReleaseInStream()) + { _inStream.Release(); return S_OK; } + +Z7_COM7F_IMF(CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; - do + + ELzmaFinishMode finishMode = LZMA_FINISH_ANY; + if (_outSizeDefined) { - if (_inPos == _inSize) + const UInt64 rem = _outSize - _outProcessed; + if (size >= rem) { - _inPos = _inSize = 0; - RINOK(_inStream->Read(_inBuf, _inBufSizeAllocated, &_inSize)); + size = (UInt32)rem; + if (FinishStream) + finishMode = LZMA_FINISH_END; } + } + + HRESULT readRes = S_OK; + + for (;;) + { + if (_inPos == _inLim && readRes == S_OK) { - SizeT inProcessed = _inSize - _inPos; + _inPos = _inLim = 0; + readRes = _inStream->Read(_inBuf, _inBufSize, &_inLim); + } - if (_outSizeDefined) - { - const UInt64 rem = _outSize - _outSizeProcessed; - if (rem < size) - size = (UInt32)rem; - } + SizeT inProcessed = _inLim - _inPos; + SizeT outProcessed = size; + ELzmaStatus status; + + const SRes res = LzmaDec_DecodeToBuf(&_state, (Byte *)data, &outProcessed, + _inBuf + _inPos, &inProcessed, finishMode, &status); + + _lzmaStatus = status; + _inPos += (UInt32)inProcessed; + _inProcessed += inProcessed; + _outProcessed += outProcessed; + size -= (UInt32)outProcessed; + data = (Byte *)data + outProcessed; + if (processedSize) + *processedSize += (UInt32)outProcessed; + + if (res != 0) + return S_FALSE; + + /* + if (status == LZMA_STATUS_FINISHED_WITH_MARK) + return readRes; - SizeT outProcessed = size; - ELzmaStatus status; - SRes res = LzmaDec_DecodeToBuf(&_state, (Byte *)data, &outProcessed, - _inBuf + _inPos, &inProcessed, LZMA_FINISH_ANY, &status); - _inPos += (UInt32)inProcessed; - _inSizeProcessed += inProcessed; - _outSizeProcessed += outProcessed; - size -= (UInt32)outProcessed; - data = (Byte *)data + outProcessed; - if (processedSize) - *processedSize += (UInt32)outProcessed; - RINOK(SResToHRESULT(res)); - if (inProcessed == 0 && outProcessed == 0) - return S_OK; + if (size == 0 && status != LZMA_STATUS_NEEDS_MORE_INPUT) + { + if (FinishStream + && _outSizeDefined && _outProcessed >= _outSize + && status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) + return S_FALSE; + return readRes; } + */ + + if (inProcessed == 0 && outProcessed == 0) + return readRes; } - while (size != 0); - return S_OK; } + HRESULT CDecoder::CodeResume(ISequentialOutStream *outStream, const UInt64 *outSize, ICompressProgressInfo *progress) { SetOutStreamSizeResume(outSize); return CodeSpec(_inStream, outStream, progress); } + HRESULT CDecoder::ReadFromInputStream(void *data, UInt32 size, UInt32 *processedSize) { - RINOK(CreateInputBuffer()); + RINOK(CreateInputBuffer()) + if (processedSize) *processedSize = 0; - while (size > 0) + + HRESULT readRes = S_OK; + + while (size != 0) { - if (_inPos == _inSize) + if (_inPos == _inLim) { - _inPos = _inSize = 0; - RINOK(_inStream->Read(_inBuf, _inBufSizeAllocated, &_inSize)); - if (_inSize == 0) + _inPos = _inLim = 0; + if (readRes == S_OK) + readRes = _inStream->Read(_inBuf, _inBufSize, &_inLim); + if (_inLim == 0) break; } - { - UInt32 curSize = _inSize - _inPos; - if (curSize > size) - curSize = size; - memcpy(data, _inBuf + _inPos, curSize); - _inPos += curSize; - _inSizeProcessed += curSize; - size -= curSize; - data = (Byte *)data + curSize; - if (processedSize) - *processedSize += curSize; - } + + UInt32 cur = _inLim - _inPos; + if (cur > size) + cur = size; + memcpy(data, _inBuf + _inPos, cur); + _inPos += cur; + _inProcessed += cur; + size -= cur; + data = (Byte *)data + cur; + if (processedSize) + *processedSize += cur; } - return S_OK; + + return readRes; } #endif diff --git a/3rdparty/lzma/CPP/7zip/Compress/LzmaDecoder.h b/3rdparty/lzma/CPP/7zip/Compress/LzmaDecoder.h index f1f839a4f1b..095e76ff3a4 100644 --- a/3rdparty/lzma/CPP/7zip/Compress/LzmaDecoder.h +++ b/3rdparty/lzma/CPP/7zip/Compress/LzmaDecoder.h @@ -1,8 +1,9 @@ // LzmaDecoder.h -#ifndef __LZMA_DECODER_H -#define __LZMA_DECODER_H +#ifndef ZIP7_INC_LZMA_DECODER_H +#define ZIP7_INC_LZMA_DECODER_H +// #include "../../../C/Alloc.h" #include "../../../C/LzmaDec.h" #include "../../Common/MyCom.h" @@ -11,79 +12,100 @@ namespace NCompress { namespace NLzma { -class CDecoder: +class CDecoder Z7_final: public ICompressCoder, public ICompressSetDecoderProperties2, public ICompressSetFinishMode, + public ICompressGetInStreamProcessedSize, public ICompressSetBufSize, - #ifndef NO_READ_FROM_CODER + #ifndef Z7_NO_READ_FROM_CODER public ICompressSetInStream, public ICompressSetOutStreamSize, public ISequentialInStream, - #endif + #endif public CMyUnknownImp { - CMyComPtr<ISequentialInStream> _inStream; - Byte *_inBuf; - UInt32 _inPos; - UInt32 _inSize; - CLzmaDec _state; + Z7_COM_QI_BEGIN2(ICompressCoder) + Z7_COM_QI_ENTRY(ICompressSetDecoderProperties2) + Z7_COM_QI_ENTRY(ICompressSetFinishMode) + Z7_COM_QI_ENTRY(ICompressGetInStreamProcessedSize) + Z7_COM_QI_ENTRY(ICompressSetBufSize) + #ifndef Z7_NO_READ_FROM_CODER + Z7_COM_QI_ENTRY(ICompressSetInStream) + Z7_COM_QI_ENTRY(ICompressSetOutStreamSize) + Z7_COM_QI_ENTRY(ISequentialInStream) + #endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(ICompressCoder) +public: + Z7_IFACE_COM7_IMP(ICompressSetDecoderProperties2) +private: + Z7_IFACE_COM7_IMP(ICompressSetFinishMode) + Z7_IFACE_COM7_IMP(ICompressGetInStreamProcessedSize) + // Z7_IFACE_COM7_IMP(ICompressSetOutStreamSize) + + Z7_IFACE_COM7_IMP(ICompressSetBufSize) + + #ifndef Z7_NO_READ_FROM_CODER +public: + Z7_IFACE_COM7_IMP(ICompressSetInStream) +private: + Z7_IFACE_COM7_IMP(ISequentialInStream) + Z7_IFACE_COM7_IMP(ICompressSetOutStreamSize) + #else + Z7_COM7F_IMF(SetOutStreamSize(const UInt64 *outSize)); + #endif + +public: + bool FinishStream; // set it before decoding, if you need to decode full LZMA stream +private: bool _propsWereSet; bool _outSizeDefined; - UInt64 _outSize; - UInt64 _inSizeProcessed; - UInt64 _outSizeProcessed; - UInt32 _inBufSizeAllocated; + UInt32 _outStep; UInt32 _inBufSize; - UInt32 _outBufSize; - SizeT _wrPos; + UInt32 _inBufSizeNew; + + ELzmaStatus _lzmaStatus; + UInt32 _inPos; + UInt32 _inLim; + Byte *_inBuf; + + UInt64 _outSize; + UInt64 _inProcessed; + UInt64 _outProcessed; + + // CAlignOffsetAlloc _alloc; + + CLzmaDec _state; HRESULT CreateInputBuffer(); HRESULT CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress); void SetOutStreamSizeResume(const UInt64 *outSize); + #ifndef Z7_NO_READ_FROM_CODER +private: + CMyComPtr<ISequentialInStream> _inStream; public: - MY_QUERYINTERFACE_BEGIN2(ICompressCoder) - MY_QUERYINTERFACE_ENTRY(ICompressSetDecoderProperties2) - MY_QUERYINTERFACE_ENTRY(ICompressSetFinishMode) - MY_QUERYINTERFACE_ENTRY(ICompressSetBufSize) - #ifndef NO_READ_FROM_CODER - MY_QUERYINTERFACE_ENTRY(ICompressSetInStream) - MY_QUERYINTERFACE_ENTRY(ICompressSetOutStreamSize) - MY_QUERYINTERFACE_ENTRY(ISequentialInStream) - #endif - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); - STDMETHOD(SetFinishMode)(UInt32 finishMode); - STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); - STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size); - STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size); - - #ifndef NO_READ_FROM_CODER - - STDMETHOD(SetInStream)(ISequentialInStream *inStream); - STDMETHOD(ReleaseInStream)(); - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - HRESULT CodeResume(ISequentialOutStream *outStream, const UInt64 *outSize, ICompressProgressInfo *progress); HRESULT ReadFromInputStream(void *data, UInt32 size, UInt32 *processedSize); - UInt64 GetInputProcessedSize() const { return _inSizeProcessed; } - - #endif - - bool FinishStream; // set it before decoding, if you need to decode full LZMA stream - - bool NeedMoreInput; // it's set by decoder, if it needs more input data to decode stream + #endif +public: CDecoder(); - virtual ~CDecoder(); - - UInt64 GetOutputProcessedSize() const { return _outSizeProcessed; } + ~CDecoder(); + + UInt64 GetInputProcessedSize() const { return _inProcessed; } + UInt64 GetOutputProcessedSize() const { return _outProcessed; } + bool NeedsMoreInput() const { return _lzmaStatus == LZMA_STATUS_NEEDS_MORE_INPUT; } + bool CheckFinishStatus(bool withEndMark) const + { + return _lzmaStatus == (withEndMark ? + LZMA_STATUS_FINISHED_WITH_MARK : + LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK); + } }; }} diff --git a/3rdparty/lzma/CPP/7zip/Compress/LzmaEncoder.cpp b/3rdparty/lzma/CPP/7zip/Compress/LzmaEncoder.cpp index 0a7e294d4f9..08e3ba53f9b 100644 --- a/3rdparty/lzma/CPP/7zip/Compress/LzmaEncoder.cpp +++ b/3rdparty/lzma/CPP/7zip/Compress/LzmaEncoder.cpp @@ -9,13 +9,28 @@ #include "LzmaEncoder.h" +// #define LOG_LZMA_THREADS + +#ifdef LOG_LZMA_THREADS + +#include <stdio.h> + +#include "../../Common/IntToString.h" +#include "../../Windows/TimeUtils.h" + +EXTERN_C_BEGIN +void LzmaEnc_GetLzThreads(CLzmaEncHandle pp, HANDLE lz_threads[2]); +EXTERN_C_END + +#endif + namespace NCompress { namespace NLzma { CEncoder::CEncoder() { _encoder = NULL; - _encoder = LzmaEnc_Create(&g_Alloc); + _encoder = LzmaEnc_Create(&g_AlignedAlloc); if (!_encoder) throw 1; } @@ -23,49 +38,51 @@ CEncoder::CEncoder() CEncoder::~CEncoder() { if (_encoder) - LzmaEnc_Destroy(_encoder, &g_Alloc, &g_BigAlloc); + LzmaEnc_Destroy(_encoder, &g_AlignedAlloc, &g_BigAlloc); } -static inline wchar_t GetUpperChar(wchar_t c) +static inline wchar_t GetLowCharFast(wchar_t c) { - if (c >= 'a' && c <= 'z') - c -= 0x20; - return c; + return c |= 0x20; } static int ParseMatchFinder(const wchar_t *s, int *btMode, int *numHashBytes) { - wchar_t c = GetUpperChar(*s++); - if (c == L'H') + const wchar_t c = GetLowCharFast(*s++); + if (c == 'h') { - if (GetUpperChar(*s++) != L'C') + if (GetLowCharFast(*s++) != 'c') return 0; - int numHashBytesLoc = (int)(*s++ - L'0'); - if (numHashBytesLoc < 4 || numHashBytesLoc > 4) + const int num = (int)(*s++ - L'0'); + if (num < 4 || num > 5) return 0; if (*s != 0) return 0; *btMode = 0; - *numHashBytes = numHashBytesLoc; + *numHashBytes = num; return 1; } - if (c != L'B') + if (c != 'b') return 0; - if (GetUpperChar(*s++) != L'T') - return 0; - int numHashBytesLoc = (int)(*s++ - L'0'); - if (numHashBytesLoc < 2 || numHashBytesLoc > 4) - return 0; - if (*s != 0) - return 0; - *btMode = 1; - *numHashBytes = numHashBytesLoc; - return 1; + { + if (GetLowCharFast(*s++) != 't') + return 0; + const int num = (int)(*s++ - L'0'); + if (num < 2 || num > 5) + return 0; + if (*s != 0) + return 0; + *btMode = 1; + *numHashBytes = num; + return 1; + } } -#define SET_PROP_32(_id_, _dest_) case NCoderPropID::_id_: ep._dest_ = v; break; +#define SET_PROP_32(_id_, _dest_) case NCoderPropID::_id_: ep._dest_ = (int)v; break; +#define SET_PROP_32U(_id_, _dest_) case NCoderPropID::_id_: ep._dest_ = v; break; +HRESULT SetLzmaProp(PROPID propID, const PROPVARIANT &prop, CLzmaEncProps &ep); HRESULT SetLzmaProp(PROPID propID, const PROPVARIANT &prop, CLzmaEncProps &ep) { if (propID == NCoderPropID::kMatchFinder) @@ -74,25 +91,70 @@ HRESULT SetLzmaProp(PROPID propID, const PROPVARIANT &prop, CLzmaEncProps &ep) return E_INVALIDARG; return ParseMatchFinder(prop.bstrVal, &ep.btMode, &ep.numHashBytes) ? S_OK : E_INVALIDARG; } + + if (propID == NCoderPropID::kAffinity) + { + if (prop.vt == VT_UI8) + ep.affinity = prop.uhVal.QuadPart; + else + return E_INVALIDARG; + return S_OK; + } + + if (propID == NCoderPropID::kHashBits) + { + if (prop.vt == VT_UI4) + ep.numHashOutBits = prop.ulVal; + else + return E_INVALIDARG; + return S_OK; + } + if (propID > NCoderPropID::kReduceSize) return S_OK; + if (propID == NCoderPropID::kReduceSize) { if (prop.vt == VT_UI8) ep.reduceSize = prop.uhVal.QuadPart; + else + return E_INVALIDARG; return S_OK; } + + if (propID == NCoderPropID::kDictionarySize) + { + if (prop.vt == VT_UI8) + { + // 21.03 : we support 64-bit VT_UI8 for dictionary and (dict == 4 GiB) + const UInt64 v = prop.uhVal.QuadPart; + if (v > ((UInt64)1 << 32)) + return E_INVALIDARG; + UInt32 dict; + if (v == ((UInt64)1 << 32)) + dict = (UInt32)(Int32)-1; + else + dict = (UInt32)v; + ep.dictSize = dict; + return S_OK; + } + } + if (prop.vt != VT_UI4) return E_INVALIDARG; - UInt32 v = prop.ulVal; + const UInt32 v = prop.ulVal; switch (propID) { - case NCoderPropID::kDefaultProp: if (v > 31) return E_INVALIDARG; ep.dictSize = (UInt32)1 << (unsigned)v; break; + case NCoderPropID::kDefaultProp: + if (v > 32) + return E_INVALIDARG; + ep.dictSize = (v == 32) ? (UInt32)(Int32)-1 : (UInt32)1 << (unsigned)v; + break; SET_PROP_32(kLevel, level) SET_PROP_32(kNumFastBytes, fb) - SET_PROP_32(kMatchFinderCycles, mc) + SET_PROP_32U(kMatchFinderCycles, mc) SET_PROP_32(kAlgorithm, algo) - SET_PROP_32(kDictionarySize, dictSize) + SET_PROP_32U(kDictionarySize, dictSize) SET_PROP_32(kPosStateBits, pb) SET_PROP_32(kLitPosBits, lp) SET_PROP_32(kLitContextBits, lc) @@ -102,8 +164,8 @@ HRESULT SetLzmaProp(PROPID propID, const PROPVARIANT &prop, CLzmaEncProps &ep) return S_OK; } -STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, - const PROPVARIANT *coderProps, UInt32 numProps) +Z7_COM7F_IMF(CEncoder::SetCoderProperties(const PROPID *propIDs, + const PROPVARIANT *coderProps, UInt32 numProps)) { CLzmaEncProps props; LzmaEncProps_Init(&props); @@ -111,41 +173,183 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, for (UInt32 i = 0; i < numProps; i++) { const PROPVARIANT &prop = coderProps[i]; - PROPID propID = propIDs[i]; + const PROPID propID = propIDs[i]; switch (propID) { case NCoderPropID::kEndMarker: - if (prop.vt != VT_BOOL) return E_INVALIDARG; props.writeEndMark = (prop.boolVal != VARIANT_FALSE); break; + if (prop.vt != VT_BOOL) + return E_INVALIDARG; + props.writeEndMark = (prop.boolVal != VARIANT_FALSE); + break; default: - RINOK(SetLzmaProp(propID, prop, props)); + RINOK(SetLzmaProp(propID, prop, props)) } } return SResToHRESULT(LzmaEnc_SetProps(_encoder, &props)); } -STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) + +Z7_COM7F_IMF(CEncoder::SetCoderPropertiesOpt(const PROPID *propIDs, + const PROPVARIANT *coderProps, UInt32 numProps)) +{ + for (UInt32 i = 0; i < numProps; i++) + { + const PROPVARIANT &prop = coderProps[i]; + const PROPID propID = propIDs[i]; + if (propID == NCoderPropID::kExpectedDataSize) + if (prop.vt == VT_UI8) + LzmaEnc_SetDataSize(_encoder, prop.uhVal.QuadPart); + } + return S_OK; +} + + +Z7_COM7F_IMF(CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)) { Byte props[LZMA_PROPS_SIZE]; - size_t size = LZMA_PROPS_SIZE; - RINOK(LzmaEnc_WriteProperties(_encoder, props, &size)); + SizeT size = LZMA_PROPS_SIZE; + RINOK(LzmaEnc_WriteProperties(_encoder, props, &size)) return WriteStream(outStream, props, size); } -STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress) + +#define RET_IF_WRAP_ERROR(wrapRes, sRes, sResErrorCode) \ + if (wrapRes != S_OK /* && (sRes == SZ_OK || sRes == sResErrorCode) */) return wrapRes; + + + +#ifdef LOG_LZMA_THREADS + +static inline UInt64 GetTime64(const FILETIME &t) { return ((UInt64)t.dwHighDateTime << 32) | t.dwLowDateTime; } + +static void PrintNum(UInt64 val, unsigned numDigits, char c = ' ') +{ + char temp[64]; + char *p = temp + 32; + ConvertUInt64ToString(val, p); + unsigned len = (unsigned)strlen(p); + for (; len < numDigits; len++) + *--p = c; + printf("%s", p); +} + +static void PrintTime(const char *s, UInt64 val, UInt64 total) +{ + printf(" %s :", s); + const UInt32 kFreq = 10000000; + UInt64 sec = val / kFreq; + PrintNum(sec, 6); + printf(" ."); + UInt32 ms = (UInt32)(val - (sec * kFreq)) / (kFreq / 1000); + PrintNum(ms, 3, '0'); + + while (val > ((UInt64)1 << 56)) + { + val >>= 1; + total >>= 1; + } + + UInt64 percent = 0; + if (total != 0) + percent = val * 100 / total; + printf(" ="); + PrintNum(percent, 4); + printf("%%"); +} + + +struct CBaseStat +{ + UInt64 kernelTime, userTime; + + BOOL Get(HANDLE thread, const CBaseStat *prevStat) + { + FILETIME creationTimeFT, exitTimeFT, kernelTimeFT, userTimeFT; + BOOL res = GetThreadTimes(thread + , &creationTimeFT, &exitTimeFT, &kernelTimeFT, &userTimeFT); + if (res) + { + kernelTime = GetTime64(kernelTimeFT); + userTime = GetTime64(userTimeFT); + if (prevStat) + { + kernelTime -= prevStat->kernelTime; + userTime -= prevStat->userTime; + } + } + return res; + } +}; + + +static void PrintStat(HANDLE thread, UInt64 totalTime, const CBaseStat *prevStat) +{ + CBaseStat newStat; + if (!newStat.Get(thread, prevStat)) + return; + + PrintTime("K", newStat.kernelTime, totalTime); + + const UInt64 processTime = newStat.kernelTime + newStat.userTime; + + PrintTime("U", newStat.userTime, totalTime); + PrintTime("S", processTime, totalTime); + printf("\n"); + // PrintTime("G ", totalTime, totalTime); +} + +#endif + + + +Z7_COM7F_IMF(CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)) { - CSeqInStreamWrap inWrap(inStream); - CSeqOutStreamWrap outWrap(outStream); - CCompressProgressWrap progressWrap(progress); + CSeqInStreamWrap inWrap; + CSeqOutStreamWrap outWrap; + CCompressProgressWrap progressWrap; + + inWrap.Init(inStream); + outWrap.Init(outStream); + progressWrap.Init(progress); + + #ifdef LOG_LZMA_THREADS + + FILETIME startTimeFT; + NWindows::NTime::GetCurUtcFileTime(startTimeFT); + UInt64 totalTime = GetTime64(startTimeFT); + CBaseStat oldStat; + if (!oldStat.Get(GetCurrentThread(), NULL)) + return E_FAIL; + + #endif + + + SRes res = LzmaEnc_Encode(_encoder, &outWrap.vt, &inWrap.vt, + progress ? &progressWrap.vt : NULL, &g_AlignedAlloc, &g_BigAlloc); - SRes res = LzmaEnc_Encode(_encoder, &outWrap.p, &inWrap.p, progress ? &progressWrap.p : NULL, &g_Alloc, &g_BigAlloc); _inputProcessed = inWrap.Processed; - if (res == SZ_ERROR_READ && inWrap.Res != S_OK) - return inWrap.Res; - if (res == SZ_ERROR_WRITE && outWrap.Res != S_OK) - return outWrap.Res; - if (res == SZ_ERROR_PROGRESS && progressWrap.Res != S_OK) - return progressWrap.Res; + + RET_IF_WRAP_ERROR(inWrap.Res, res, SZ_ERROR_READ) + RET_IF_WRAP_ERROR(outWrap.Res, res, SZ_ERROR_WRITE) + RET_IF_WRAP_ERROR(progressWrap.Res, res, SZ_ERROR_PROGRESS) + + + #ifdef LOG_LZMA_THREADS + + NWindows::NTime::GetCurUtcFileTime(startTimeFT); + totalTime = GetTime64(startTimeFT) - totalTime; + HANDLE lz_threads[2]; + LzmaEnc_GetLzThreads(_encoder, lz_threads); + printf("\n"); + printf("Main: "); PrintStat(GetCurrentThread(), totalTime, &oldStat); + printf("Hash: "); PrintStat(lz_threads[0], totalTime, NULL); + printf("BinT: "); PrintStat(lz_threads[1], totalTime, NULL); + // PrintTime("Total: ", totalTime, totalTime); + printf("\n"); + + #endif + return SResToHRESULT(res); } diff --git a/3rdparty/lzma/CPP/7zip/Compress/LzmaEncoder.h b/3rdparty/lzma/CPP/7zip/Compress/LzmaEncoder.h index f919ac2cc49..2836d7df5b6 100644 --- a/3rdparty/lzma/CPP/7zip/Compress/LzmaEncoder.h +++ b/3rdparty/lzma/CPP/7zip/Compress/LzmaEncoder.h @@ -1,7 +1,7 @@ // LzmaEncoder.h -#ifndef __LZMA_ENCODER_H -#define __LZMA_ENCODER_H +#ifndef ZIP7_INC_LZMA_ENCODER_H +#define ZIP7_INC_LZMA_ENCODER_H #include "../../../C/LzmaEnc.h" @@ -12,25 +12,32 @@ namespace NCompress { namespace NLzma { -class CEncoder: +class CEncoder Z7_final: public ICompressCoder, public ICompressSetCoderProperties, public ICompressWriteCoderProperties, + public ICompressSetCoderPropertiesOpt, public CMyUnknownImp { + Z7_COM_UNKNOWN_IMP_4( + ICompressCoder, + ICompressSetCoderProperties, + ICompressWriteCoderProperties, + ICompressSetCoderPropertiesOpt) + Z7_IFACE_COM7_IMP(ICompressCoder) +public: + Z7_IFACE_COM7_IMP(ICompressSetCoderProperties) + Z7_IFACE_COM7_IMP(ICompressWriteCoderProperties) + Z7_IFACE_COM7_IMP(ICompressSetCoderPropertiesOpt) + CLzmaEncHandle _encoder; UInt64 _inputProcessed; -public: - MY_UNKNOWN_IMP3(ICompressCoder, ICompressSetCoderProperties, ICompressWriteCoderProperties) - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); - STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream); CEncoder(); - virtual ~CEncoder(); + ~CEncoder(); + UInt64 GetInputProcessedSize() const { return _inputProcessed; } + bool IsWriteEndMark() const { return LzmaEnc_IsWriteEndMark(_encoder) != 0; } }; }} diff --git a/3rdparty/lzma/CPP/7zip/Compress/LzmaRegister.cpp b/3rdparty/lzma/CPP/7zip/Compress/LzmaRegister.cpp index c802a99fa0e..887f7a2db1e 100644 --- a/3rdparty/lzma/CPP/7zip/Compress/LzmaRegister.cpp +++ b/3rdparty/lzma/CPP/7zip/Compress/LzmaRegister.cpp @@ -6,7 +6,7 @@ #include "LzmaDecoder.h" -#ifndef EXTRACT_ONLY +#ifndef Z7_EXTRACT_ONLY #include "LzmaEncoder.h" #endif diff --git a/3rdparty/lzma/CPP/7zip/Compress/PpmdDecoder.cpp b/3rdparty/lzma/CPP/7zip/Compress/PpmdDecoder.cpp index c868730ea00..1238df60cb9 100644 --- a/3rdparty/lzma/CPP/7zip/Compress/PpmdDecoder.cpp +++ b/3rdparty/lzma/CPP/7zip/Compress/PpmdDecoder.cpp @@ -1,5 +1,4 @@ // PpmdDecoder.cpp -// 2009-03-11 : Igor Pavlov : Public domain #include "StdAfx.h" @@ -13,13 +12,13 @@ namespace NCompress { namespace NPpmd { -static const UInt32 kBufSize = (1 << 20); +static const UInt32 kBufSize = (1 << 16); enum { kStatus_NeedInit, kStatus_Normal, - kStatus_Finished, + kStatus_Finished_With_Mark, kStatus_Error }; @@ -29,12 +28,12 @@ CDecoder::~CDecoder() Ppmd7_Free(&_ppmd, &g_BigAlloc); } -STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *props, UInt32 size) +Z7_COM7F_IMF(CDecoder::SetDecoderProperties2(const Byte *props, UInt32 size)) { if (size < 5) return E_INVALIDARG; _order = props[0]; - UInt32 memSize = GetUi32(props + 1); + const UInt32 memSize = GetUi32(props + 1); if (_order < PPMD7_MIN_ORDER || _order > PPMD7_MAX_ORDER || memSize < PPMD7_MIN_MEM_SIZE || @@ -47,23 +46,36 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *props, UInt32 size) return S_OK; } +#define MY_rangeDec _ppmd.rc.dec + +#define CHECK_EXTRA_ERROR \ + if (_inStream.Extra) { \ + _status = kStatus_Error; \ + return (_res = (_inStream.Res != SZ_OK ? _inStream.Res: S_FALSE)); } + + HRESULT CDecoder::CodeSpec(Byte *memStream, UInt32 size) { + if (_res != S_OK) + return _res; + switch (_status) { - case kStatus_Finished: return S_OK; + case kStatus_Finished_With_Mark: return S_OK; case kStatus_Error: return S_FALSE; case kStatus_NeedInit: _inStream.Init(); - if (!Ppmd7z_RangeDec_Init(&_rangeDec)) + if (!Ppmd7z_RangeDec_Init(&MY_rangeDec)) { _status = kStatus_Error; - return S_FALSE; + return (_res = S_FALSE); } + CHECK_EXTRA_ERROR _status = kStatus_Normal; Ppmd7_Init(&_ppmd, _order); break; } + if (_outSizeDefined) { const UInt64 rem = _outSize - _processedSize; @@ -71,29 +83,54 @@ HRESULT CDecoder::CodeSpec(Byte *memStream, UInt32 size) size = (UInt32)rem; } - UInt32 i; int sym = 0; - for (i = 0; i != size; i++) { - sym = Ppmd7_DecodeSymbol(&_ppmd, &_rangeDec.p); - if (_inStream.Extra || sym < 0) - break; - memStream[i] = (Byte)sym; + Byte *buf = memStream; + const Byte *lim = buf + size; + for (; buf != lim; buf++) + { + sym = Ppmd7z_DecodeSymbol(&_ppmd); + if (_inStream.Extra || sym < 0) + break; + *buf = (Byte)sym; + } + /* + buf = Ppmd7z_DecodeSymbols(&_ppmd, buf, lim); + sym = _ppmd.LastSymbol; + */ + _processedSize += (size_t)(buf - memStream); + } + + CHECK_EXTRA_ERROR + + if (sym >= 0) + { + if (!FinishStream + || !_outSizeDefined + || _outSize != _processedSize + || MY_rangeDec.Code == 0) + return S_OK; + /* + // We can decode additional End Marker here: + sym = Ppmd7z_DecodeSymbol(&_ppmd); + CHECK_EXTRA_ERROR + */ } - _processedSize += i; - if (_inStream.Extra) + if (sym != PPMD7_SYM_END || MY_rangeDec.Code != 0) { _status = kStatus_Error; - return _inStream.Res; + return (_res = S_FALSE); } - if (sym < 0) - _status = (sym < -1) ? kStatus_Error : kStatus_Finished; + + _status = kStatus_Finished_With_Mark; return S_OK; } -STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress) + + +Z7_COM7F_IMF(CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)) { if (!_outBuf) { @@ -108,51 +145,69 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream do { const UInt64 startPos = _processedSize; - HRESULT res = CodeSpec(_outBuf, kBufSize); - size_t processed = (size_t)(_processedSize - startPos); - RINOK(WriteStream(outStream, _outBuf, processed)); - RINOK(res); - if (_status == kStatus_Finished) + const HRESULT res = CodeSpec(_outBuf, kBufSize); + const size_t processed = (size_t)(_processedSize - startPos); + RINOK(WriteStream(outStream, _outBuf, processed)) + RINOK(res) + if (_status == kStatus_Finished_With_Mark) break; if (progress) { - UInt64 inSize = _inStream.GetProcessed(); - RINOK(progress->SetRatioInfo(&inSize, &_processedSize)); + const UInt64 inProcessed = _inStream.GetProcessed(); + RINOK(progress->SetRatioInfo(&inProcessed, &_processedSize)) } } while (!_outSizeDefined || _processedSize < _outSize); + + if (FinishStream && inSize && *inSize != _inStream.GetProcessed()) + return S_FALSE; + return S_OK; } -STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize) + +Z7_COM7F_IMF(CDecoder::SetOutStreamSize(const UInt64 *outSize)) { _outSizeDefined = (outSize != NULL); if (_outSizeDefined) _outSize = *outSize; _processedSize = 0; _status = kStatus_NeedInit; + _res = SZ_OK; + return S_OK; +} + +Z7_COM7F_IMF(CDecoder::SetFinishMode(UInt32 finishMode)) +{ + FinishStream = (finishMode != 0); + return S_OK; +} + +Z7_COM7F_IMF(CDecoder::GetInStreamProcessedSize(UInt64 *value)) +{ + *value = _inStream.GetProcessed(); return S_OK; } -#ifndef NO_READ_FROM_CODER +#ifndef Z7_NO_READ_FROM_CODER -STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) +Z7_COM7F_IMF(CDecoder::SetInStream(ISequentialInStream *inStream)) { InSeqStream = inStream; _inStream.Stream = inStream; return S_OK; } -STDMETHODIMP CDecoder::ReleaseInStream() +Z7_COM7F_IMF(CDecoder::ReleaseInStream()) { InSeqStream.Release(); return S_OK; } -STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)) { const UInt64 startPos = _processedSize; - HRESULT res = CodeSpec((Byte *)data, size); + const HRESULT res = CodeSpec((Byte *)data, size); if (processedSize) *processedSize = (UInt32)(_processedSize - startPos); return res; diff --git a/3rdparty/lzma/CPP/7zip/Compress/PpmdDecoder.h b/3rdparty/lzma/CPP/7zip/Compress/PpmdDecoder.h index 8ebcd700c7d..22e5bd49587 100644 --- a/3rdparty/lzma/CPP/7zip/Compress/PpmdDecoder.h +++ b/3rdparty/lzma/CPP/7zip/Compress/PpmdDecoder.h @@ -1,37 +1,63 @@ // PpmdDecoder.h -// 2009-03-11 : Igor Pavlov : Public domain -#ifndef __COMPRESS_PPMD_DECODER_H -#define __COMPRESS_PPMD_DECODER_H +#ifndef ZIP7_INC_COMPRESS_PPMD_DECODER_H +#define ZIP7_INC_COMPRESS_PPMD_DECODER_H #include "../../../C/Ppmd7.h" #include "../../Common/MyCom.h" -#include "../Common/CWrappers.h" - #include "../ICoder.h" +#include "../Common/CWrappers.h" + namespace NCompress { namespace NPpmd { -class CDecoder : +class CDecoder Z7_final: public ICompressCoder, public ICompressSetDecoderProperties2, - #ifndef NO_READ_FROM_CODER + public ICompressSetFinishMode, + public ICompressGetInStreamProcessedSize, + #ifndef Z7_NO_READ_FROM_CODER public ICompressSetInStream, public ICompressSetOutStreamSize, public ISequentialInStream, - #endif + #endif public CMyUnknownImp { + Z7_COM_QI_BEGIN2(ICompressCoder) + Z7_COM_QI_ENTRY(ICompressSetDecoderProperties2) + Z7_COM_QI_ENTRY(ICompressSetFinishMode) + Z7_COM_QI_ENTRY(ICompressGetInStreamProcessedSize) + #ifndef Z7_NO_READ_FROM_CODER + Z7_COM_QI_ENTRY(ICompressSetInStream) + Z7_COM_QI_ENTRY(ICompressSetOutStreamSize) + Z7_COM_QI_ENTRY(ISequentialInStream) + #endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(ICompressCoder) + Z7_IFACE_COM7_IMP(ICompressSetDecoderProperties2) + Z7_IFACE_COM7_IMP(ICompressSetFinishMode) + Z7_IFACE_COM7_IMP(ICompressGetInStreamProcessedSize) + #ifndef Z7_NO_READ_FROM_CODER + Z7_IFACE_COM7_IMP(ICompressSetOutStreamSize) + Z7_IFACE_COM7_IMP(ICompressSetInStream) + Z7_IFACE_COM7_IMP(ISequentialInStream) + #else + Z7_COM7F_IMF(SetOutStreamSize(const UInt64 *outSize)); + #endif + Byte *_outBuf; - CPpmd7z_RangeDec _rangeDec; CByteInBufWrap _inStream; CPpmd7 _ppmd; Byte _order; + bool FinishStream; bool _outSizeDefined; + HRESULT _res; int _status; UInt64 _outSize; UInt64 _processedSize; @@ -40,34 +66,17 @@ class CDecoder : public: - #ifndef NO_READ_FROM_CODER + #ifndef Z7_NO_READ_FROM_CODER CMyComPtr<ISequentialInStream> InSeqStream; - MY_UNKNOWN_IMP4( - ICompressSetDecoderProperties2, - ICompressSetInStream, - ICompressSetOutStreamSize, - ISequentialInStream) - #else - MY_UNKNOWN_IMP1( - ICompressSetDecoderProperties2) - #endif - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); - STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); - - #ifndef NO_READ_FROM_CODER - STDMETHOD(SetInStream)(ISequentialInStream *inStream); - STDMETHOD(ReleaseInStream)(); - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - #endif - - CDecoder(): _outBuf(NULL), _outSizeDefined(false) + #endif + + CDecoder(): + _outBuf(NULL), + FinishStream(false), + _outSizeDefined(false) { - Ppmd7z_RangeDec_CreateVTable(&_rangeDec); - _rangeDec.Stream = &_inStream.p; Ppmd7_Construct(&_ppmd); + _ppmd.rc.dec.Stream = &_inStream.vt; } ~CDecoder(); diff --git a/3rdparty/lzma/CPP/7zip/Compress/PpmdEncoder.cpp b/3rdparty/lzma/CPP/7zip/Compress/PpmdEncoder.cpp index 00ea9668b00..2dfca6df6f2 100644 --- a/3rdparty/lzma/CPP/7zip/Compress/PpmdEncoder.cpp +++ b/3rdparty/lzma/CPP/7zip/Compress/PpmdEncoder.cpp @@ -3,7 +3,6 @@ #include "StdAfx.h" #include "../../../C/Alloc.h" -#include "../../../C/CpuArch.h" #include "../Common/StreamUtils.h" @@ -21,11 +20,11 @@ void CEncProps::Normalize(int level) if (level < 0) level = 5; if (level > 9) level = 9; if (MemSize == (UInt32)(Int32)-1) - MemSize = level >= 9 ? ((UInt32)192 << 20) : ((UInt32)1 << (level + 19)); + MemSize = (UInt32)1 << (level + 19); const unsigned kMult = 16; if (MemSize / kMult > ReduceSize) { - for (unsigned i = 16; i <= 31; i++) + for (unsigned i = 16; i < 32; i++) { UInt32 m = (UInt32)1 << i; if (ReduceSize <= m / kMult) @@ -43,8 +42,8 @@ CEncoder::CEncoder(): _inBuf(NULL) { _props.Normalize(-1); - _rangeEnc.Stream = &_outStream.p; Ppmd7_Construct(&_ppmd); + _ppmd.rc.enc.Stream = &_outStream.vt; } CEncoder::~CEncoder() @@ -53,14 +52,14 @@ CEncoder::~CEncoder() Ppmd7_Free(&_ppmd, &g_BigAlloc); } -STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps) +Z7_COM7F_IMF(CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps)) { int level = -1; CEncProps props; for (UInt32 i = 0; i < numProps; i++) { const PROPVARIANT &prop = coderProps[i]; - PROPID propID = propIDs[i]; + const PROPID propID = propIDs[i]; if (propID > NCoderPropID::kReduceSize) continue; if (propID == NCoderPropID::kReduceSize) @@ -69,16 +68,50 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIA props.ReduceSize = (UInt32)prop.uhVal.QuadPart; continue; } + + if (propID == NCoderPropID::kUsedMemorySize) + { + // here we have selected (4 GiB - 1 KiB) as replacement for (4 GiB) MEM_SIZE. + const UInt32 kPpmd_Default_4g = (UInt32)0 - ((UInt32)1 << 10); + UInt32 v; + if (prop.vt == VT_UI8) + { + // 21.03 : we support 64-bit values (for 4 GiB value) + const UInt64 v64 = prop.uhVal.QuadPart; + if (v64 > ((UInt64)1 << 32)) + return E_INVALIDARG; + if (v64 == ((UInt64)1 << 32)) + v = kPpmd_Default_4g; + else + v = (UInt32)v64; + } + else if (prop.vt == VT_UI4) + v = (UInt32)prop.ulVal; + else + return E_INVALIDARG; + if (v > PPMD7_MAX_MEM_SIZE) + v = kPpmd_Default_4g; + + /* here we restrict MEM_SIZE for Encoder. + It's for better performance of encoding and decoding. + The Decoder still supports more MEM_SIZE values. */ + if (v < ((UInt32)1 << 16) || (v & 3) != 0) + return E_INVALIDARG; + // if (v < PPMD7_MIN_MEM_SIZE) return E_INVALIDARG; // (1 << 11) + /* + Supported MEM_SIZE range : + [ (1 << 11) , 0xFFFFFFFF - 12 * 3 ] - current 7-Zip's Ppmd7 constants + [ 1824 , 0xFFFFFFFF ] - real limits of Ppmd7 code + */ + props.MemSize = v; + continue; + } + if (prop.vt != VT_UI4) return E_INVALIDARG; - UInt32 v = (UInt32)prop.ulVal; + const UInt32 v = (UInt32)prop.ulVal; switch (propID) { - case NCoderPropID::kUsedMemorySize: - if (v < (1 << 16) || v > PPMD7_MAX_MEM_SIZE || (v & 3) != 0) - return E_INVALIDARG; - props.MemSize = v; - break; case NCoderPropID::kOrder: if (v < 2 || v > 32) return E_INVALIDARG; @@ -94,17 +127,17 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIA return S_OK; } -STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) +Z7_COM7F_IMF(CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)) { const UInt32 kPropSize = 5; Byte props[kPropSize]; props[0] = (Byte)_props.Order; - SetUi32(props + 1, _props.MemSize); + SetUi32(props + 1, _props.MemSize) return WriteStream(outStream, props, kPropSize); } -HRESULT CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress) +Z7_COM7F_IMF(CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)) { if (!_inBuf) { @@ -120,31 +153,39 @@ HRESULT CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outS _outStream.Stream = outStream; _outStream.Init(); - Ppmd7z_RangeEnc_Init(&_rangeEnc); - Ppmd7_Init(&_ppmd, _props.Order); + Ppmd7z_Init_RangeEnc(&_ppmd); + Ppmd7_Init(&_ppmd, (unsigned)_props.Order); UInt64 processed = 0; for (;;) { UInt32 size; - RINOK(inStream->Read(_inBuf, kBufSize, &size)); + RINOK(inStream->Read(_inBuf, kBufSize, &size)) if (size == 0) { // We don't write EndMark in PPMD-7z. - // Ppmd7_EncodeSymbol(&_ppmd, &_rangeEnc, -1); - Ppmd7z_RangeEnc_FlushData(&_rangeEnc); + // Ppmd7z_EncodeSymbol(&_ppmd, -1); + Ppmd7z_Flush_RangeEnc(&_ppmd); return _outStream.Flush(); } - for (UInt32 i = 0; i < size; i++) + const Byte *buf = _inBuf; + const Byte *lim = buf + size; + /* + for (; buf < lim; buf++) { - Ppmd7_EncodeSymbol(&_ppmd, &_rangeEnc, _inBuf[i]); + Ppmd7z_EncodeSymbol(&_ppmd, *buf); RINOK(_outStream.Res); } + */ + + Ppmd7z_EncodeSymbols(&_ppmd, buf, lim); + RINOK(_outStream.Res) + processed += size; if (progress) { - UInt64 outSize = _outStream.GetProcessed(); - RINOK(progress->SetRatioInfo(&processed, &outSize)); + const UInt64 outSize = _outStream.GetProcessed(); + RINOK(progress->SetRatioInfo(&processed, &outSize)) } } } diff --git a/3rdparty/lzma/CPP/7zip/Compress/PpmdEncoder.h b/3rdparty/lzma/CPP/7zip/Compress/PpmdEncoder.h index 671a5353e7a..057cccbec59 100644 --- a/3rdparty/lzma/CPP/7zip/Compress/PpmdEncoder.h +++ b/3rdparty/lzma/CPP/7zip/Compress/PpmdEncoder.h @@ -1,7 +1,7 @@ // PpmdEncoder.h -#ifndef __COMPRESS_PPMD_ENCODER_H -#define __COMPRESS_PPMD_ENCODER_H +#ifndef ZIP7_INC_COMPRESS_PPMD_ENCODER_H +#define ZIP7_INC_COMPRESS_PPMD_ENCODER_H #include "../../../C/Ppmd7.h" @@ -29,26 +29,17 @@ struct CEncProps void Normalize(int level); }; -class CEncoder : - public ICompressCoder, - public ICompressSetCoderProperties, - public ICompressWriteCoderProperties, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_3( + CEncoder + , ICompressCoder + , ICompressSetCoderProperties + , ICompressWriteCoderProperties +) Byte *_inBuf; CByteOutBufWrap _outStream; - CPpmd7z_RangeEnc _rangeEnc; CPpmd7 _ppmd; CEncProps _props; public: - MY_UNKNOWN_IMP3( - ICompressCoder, - ICompressSetCoderProperties, - ICompressWriteCoderProperties) - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); - STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream); CEncoder(); ~CEncoder(); }; diff --git a/3rdparty/lzma/CPP/7zip/Compress/PpmdRegister.cpp b/3rdparty/lzma/CPP/7zip/Compress/PpmdRegister.cpp index a3ebb5f3d87..fb5619c969f 100644 --- a/3rdparty/lzma/CPP/7zip/Compress/PpmdRegister.cpp +++ b/3rdparty/lzma/CPP/7zip/Compress/PpmdRegister.cpp @@ -6,7 +6,7 @@ #include "PpmdDecoder.h" -#ifndef EXTRACT_ONLY +#ifndef Z7_EXTRACT_ONLY #include "PpmdEncoder.h" #endif diff --git a/3rdparty/lzma/CPP/7zip/Compress/StdAfx.h b/3rdparty/lzma/CPP/7zip/Compress/StdAfx.h index 1cbd7feaeec..80866550d1f 100644 --- a/3rdparty/lzma/CPP/7zip/Compress/StdAfx.h +++ b/3rdparty/lzma/CPP/7zip/Compress/StdAfx.h @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../Common/Common.h" #endif diff --git a/3rdparty/lzma/CPP/7zip/Compress/XzDecoder.cpp b/3rdparty/lzma/CPP/7zip/Compress/XzDecoder.cpp new file mode 100644 index 00000000000..420bd714003 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/Compress/XzDecoder.cpp @@ -0,0 +1,150 @@ +// XzDecoder.cpp + +#include "StdAfx.h" + +#include "../../../C/Alloc.h" + +#include "../Common/CWrappers.h" + +#include "XzDecoder.h" + +namespace NCompress { +namespace NXz { + +#define RET_IF_WRAP_ERROR_CONFIRMED(wrapRes, sRes, sResErrorCode) \ + if (wrapRes != S_OK && sRes == sResErrorCode) return wrapRes; + +#define RET_IF_WRAP_ERROR(wrapRes, sRes, sResErrorCode) \ + if (wrapRes != S_OK /* && (sRes == SZ_OK || sRes == sResErrorCode) */) return wrapRes; + +static HRESULT SResToHRESULT_Code(SRes res) throw() +{ + if (res < 0) + return res; + switch (res) + { + case SZ_OK: return S_OK; + case SZ_ERROR_MEM: return E_OUTOFMEMORY; + case SZ_ERROR_UNSUPPORTED: return E_NOTIMPL; + } + return S_FALSE; +} + + +HRESULT CDecoder::Decode(ISequentialInStream *seqInStream, ISequentialOutStream *outStream, + const UInt64 *outSizeLimit, bool finishStream, ICompressProgressInfo *progress) +{ + MainDecodeSRes = SZ_OK; + MainDecodeSRes_wasUsed = false; + XzStatInfo_Clear(&Stat); + + if (!xz) + { + xz = XzDecMt_Create(&g_Alloc, &g_MidAlloc); + if (!xz) + return E_OUTOFMEMORY; + } + + CXzDecMtProps props; + XzDecMtProps_Init(&props); + + int isMT = False; + + #ifndef Z7_ST + { + props.numThreads = 1; + const UInt32 numThreads = _numThreads; + + if (_tryMt && numThreads > 1) + { + size_t memUsage = (size_t)_memUsage; + if (memUsage != _memUsage) + memUsage = (size_t)0 - 1; + props.memUseMax = memUsage; + isMT = (numThreads > 1); + } + + props.numThreads = numThreads; + } + #endif + + CSeqInStreamWrap inWrap; + CSeqOutStreamWrap outWrap; + CCompressProgressWrap progressWrap; + + inWrap.Init(seqInStream); + outWrap.Init(outStream); + progressWrap.Init(progress); + + SRes res = XzDecMt_Decode(xz, + &props, + outSizeLimit, finishStream, + &outWrap.vt, + &inWrap.vt, + &Stat, + &isMT, + progress ? &progressWrap.vt : NULL); + + MainDecodeSRes = res; + + #ifndef Z7_ST + // _tryMt = isMT; + #endif + + RET_IF_WRAP_ERROR(outWrap.Res, res, SZ_ERROR_WRITE) + RET_IF_WRAP_ERROR(progressWrap.Res, res, SZ_ERROR_PROGRESS) + RET_IF_WRAP_ERROR_CONFIRMED(inWrap.Res, res, SZ_ERROR_READ) + + // return E_OUTOFMEMORY; // for debug check + + MainDecodeSRes_wasUsed = true; + + if (res == SZ_OK && finishStream) + { + /* + if (inSize && *inSize != Stat.PhySize) + res = SZ_ERROR_DATA; + */ + if (outSizeLimit && *outSizeLimit != outWrap.Processed) + res = SZ_ERROR_DATA; + } + + return SResToHRESULT_Code(res); +} + + +Z7_COM7F_IMF(CComDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)) +{ + return Decode(inStream, outStream, outSize, _finishStream, progress); +} + +Z7_COM7F_IMF(CComDecoder::SetFinishMode(UInt32 finishMode)) +{ + _finishStream = (finishMode != 0); + return S_OK; +} + +Z7_COM7F_IMF(CComDecoder::GetInStreamProcessedSize(UInt64 *value)) +{ + *value = Stat.InSize; + return S_OK; +} + +#ifndef Z7_ST + +Z7_COM7F_IMF(CComDecoder::SetNumberOfThreads(UInt32 numThreads)) +{ + _numThreads = numThreads; + return S_OK; +} + +Z7_COM7F_IMF(CComDecoder::SetMemLimit(UInt64 memUsage)) +{ + _memUsage = memUsage; + return S_OK; +} + +#endif + +}} diff --git a/3rdparty/lzma/CPP/7zip/Compress/XzDecoder.h b/3rdparty/lzma/CPP/7zip/Compress/XzDecoder.h new file mode 100644 index 00000000000..40ed4f5c5cd --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/Compress/XzDecoder.h @@ -0,0 +1,86 @@ +// XzDecoder.h + +#ifndef ZIP7_INC_XZ_DECODER_H +#define ZIP7_INC_XZ_DECODER_H + +#include "../../../C/Xz.h" + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +namespace NCompress { +namespace NXz { + +struct CDecoder +{ + CXzDecMtHandle xz; + int _tryMt; + UInt32 _numThreads; + UInt64 _memUsage; + + SRes MainDecodeSRes; // it's not HRESULT + bool MainDecodeSRes_wasUsed; + CXzStatInfo Stat; + + CDecoder(): + xz(NULL), + _tryMt(True), + _numThreads(1), + _memUsage((UInt64)(sizeof(size_t)) << 28), + MainDecodeSRes(SZ_OK), + MainDecodeSRes_wasUsed(false) + {} + + ~CDecoder() + { + if (xz) + XzDecMt_Destroy(xz); + } + + /* Decode() can return S_OK, if there is data after good xz streams, and that data is not new xz stream. + check also (Stat.DataAfterEnd) flag */ + + HRESULT Decode(ISequentialInStream *seqInStream, ISequentialOutStream *outStream, + const UInt64 *outSizeLimit, bool finishStream, ICompressProgressInfo *compressProgress); +}; + + +class CComDecoder Z7_final: + public ICompressCoder, + public ICompressSetFinishMode, + public ICompressGetInStreamProcessedSize, + #ifndef Z7_ST + public ICompressSetCoderMt, + public ICompressSetMemLimit, + #endif + public CMyUnknownImp, + public CDecoder +{ + Z7_COM_QI_BEGIN2(ICompressCoder) + Z7_COM_QI_ENTRY(ICompressSetFinishMode) + Z7_COM_QI_ENTRY(ICompressGetInStreamProcessedSize) + #ifndef Z7_ST + Z7_COM_QI_ENTRY(ICompressSetCoderMt) + Z7_COM_QI_ENTRY(ICompressSetMemLimit) + #endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(ICompressCoder) + Z7_IFACE_COM7_IMP(ICompressSetFinishMode) + Z7_IFACE_COM7_IMP(ICompressGetInStreamProcessedSize) + #ifndef Z7_ST + Z7_IFACE_COM7_IMP(ICompressSetCoderMt) + Z7_IFACE_COM7_IMP(ICompressSetMemLimit) + #endif + + bool _finishStream; + +public: + CComDecoder(): _finishStream(false) {} +}; + +}} + +#endif diff --git a/3rdparty/lzma/CPP/7zip/Compress/XzEncoder.cpp b/3rdparty/lzma/CPP/7zip/Compress/XzEncoder.cpp new file mode 100644 index 00000000000..33f0bde4713 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/Compress/XzEncoder.cpp @@ -0,0 +1,243 @@ +// XzEncoder.cpp + +#include "StdAfx.h" + +#include "../../../C/Alloc.h" + +#include "../../Common/MyString.h" +#include "../../Common/StringToInt.h" + +#include "../Common/CWrappers.h" +#include "../Common/StreamUtils.h" + +#include "XzEncoder.h" + +namespace NCompress { + +namespace NLzma2 { +HRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzma2Props); +} + +namespace NXz { + +void CEncoder::InitCoderProps() +{ + XzProps_Init(&xzProps); +} + +CEncoder::CEncoder() +{ + XzProps_Init(&xzProps); + _encoder = NULL; + _encoder = XzEnc_Create(&g_Alloc, &g_BigAlloc); + if (!_encoder) + throw 1; +} + +CEncoder::~CEncoder() +{ + if (_encoder) + XzEnc_Destroy(_encoder); +} + + +struct CMethodNamePair +{ + UInt32 Id; + const char *Name; +}; + +static const CMethodNamePair g_NamePairs[] = +{ + { XZ_ID_Delta, "Delta" }, + { XZ_ID_X86, "BCJ" }, + { XZ_ID_PPC, "PPC" }, + { XZ_ID_IA64, "IA64" }, + { XZ_ID_ARM, "ARM" }, + { XZ_ID_ARMT, "ARMT" }, + { XZ_ID_SPARC, "SPARC" } + // { XZ_ID_LZMA2, "LZMA2" } +}; + +static int FilterIdFromName(const wchar_t *name) +{ + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_NamePairs); i++) + { + const CMethodNamePair &pair = g_NamePairs[i]; + if (StringsAreEqualNoCase_Ascii(name, pair.Name)) + return (int)pair.Id; + } + return -1; +} + + +HRESULT CEncoder::SetCheckSize(UInt32 checkSizeInBytes) +{ + unsigned id; + switch (checkSizeInBytes) + { + case 0: id = XZ_CHECK_NO; break; + case 4: id = XZ_CHECK_CRC32; break; + case 8: id = XZ_CHECK_CRC64; break; + case 32: id = XZ_CHECK_SHA256; break; + default: return E_INVALIDARG; + } + xzProps.checkId = id; + return S_OK; +} + + +HRESULT CEncoder::SetCoderProp(PROPID propID, const PROPVARIANT &prop) +{ + if (propID == NCoderPropID::kNumThreads) + { + if (prop.vt != VT_UI4) + return E_INVALIDARG; + xzProps.numTotalThreads = (int)(prop.ulVal); + return S_OK; + } + + if (propID == NCoderPropID::kCheckSize) + { + if (prop.vt != VT_UI4) + return E_INVALIDARG; + return SetCheckSize(prop.ulVal); + } + + if (propID == NCoderPropID::kBlockSize2) + { + if (prop.vt == VT_UI4) + xzProps.blockSize = prop.ulVal; + else if (prop.vt == VT_UI8) + xzProps.blockSize = prop.uhVal.QuadPart; + else + return E_INVALIDARG; + return S_OK; + } + + if (propID == NCoderPropID::kReduceSize) + { + if (prop.vt == VT_UI8) + xzProps.reduceSize = prop.uhVal.QuadPart; + else + return E_INVALIDARG; + return S_OK; + } + + if (propID == NCoderPropID::kFilter) + { + if (prop.vt == VT_UI4) + { + const UInt32 id32 = prop.ulVal; + if (id32 == XZ_ID_Delta) + return E_INVALIDARG; + xzProps.filterProps.id = prop.ulVal; + } + else + { + if (prop.vt != VT_BSTR) + return E_INVALIDARG; + + const wchar_t *name = prop.bstrVal; + const wchar_t *end; + + UInt32 id32 = ConvertStringToUInt32(name, &end); + + if (end != name) + name = end; + else + { + if (IsString1PrefixedByString2_NoCase_Ascii(name, "Delta")) + { + name += 5; // strlen("Delta"); + id32 = XZ_ID_Delta; + } + else + { + const int filterId = FilterIdFromName(prop.bstrVal); + if (filterId < 0 /* || filterId == XZ_ID_LZMA2 */) + return E_INVALIDARG; + id32 = (unsigned)filterId; + } + } + + if (id32 == XZ_ID_Delta) + { + const wchar_t c = *name; + if (c != '-' && c != ':') + return E_INVALIDARG; + name++; + const UInt32 delta = ConvertStringToUInt32(name, &end); + if (end == name || *end != 0 || delta == 0 || delta > 256) + return E_INVALIDARG; + xzProps.filterProps.delta = delta; + } + + xzProps.filterProps.id = id32; + } + + return S_OK; + } + + return NLzma2::SetLzma2Prop(propID, prop, xzProps.lzma2Props); +} + + +Z7_COM7F_IMF(CEncoder::SetCoderProperties(const PROPID *propIDs, + const PROPVARIANT *coderProps, UInt32 numProps)) +{ + XzProps_Init(&xzProps); + + for (UInt32 i = 0; i < numProps; i++) + { + RINOK(SetCoderProp(propIDs[i], coderProps[i])) + } + + return S_OK; + // return SResToHRESULT(XzEnc_SetProps(_encoder, &xzProps)); +} + + +Z7_COM7F_IMF(CEncoder::SetCoderPropertiesOpt(const PROPID *propIDs, + const PROPVARIANT *coderProps, UInt32 numProps)) +{ + for (UInt32 i = 0; i < numProps; i++) + { + const PROPVARIANT &prop = coderProps[i]; + const PROPID propID = propIDs[i]; + if (propID == NCoderPropID::kExpectedDataSize) + if (prop.vt == VT_UI8) + XzEnc_SetDataSize(_encoder, prop.uhVal.QuadPart); + } + return S_OK; +} + + +#define RET_IF_WRAP_ERROR(wrapRes, sRes, sResErrorCode) \ + if (wrapRes != S_OK /* && (sRes == SZ_OK || sRes == sResErrorCode) */) return wrapRes; + +Z7_COM7F_IMF(CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)) +{ + CSeqInStreamWrap inWrap; + CSeqOutStreamWrap outWrap; + CCompressProgressWrap progressWrap; + + inWrap.Init(inStream); + outWrap.Init(outStream); + progressWrap.Init(progress); + + SRes res = XzEnc_SetProps(_encoder, &xzProps); + if (res == SZ_OK) + res = XzEnc_Encode(_encoder, &outWrap.vt, &inWrap.vt, progress ? &progressWrap.vt : NULL); + + // SRes res = Xz_Encode(&outWrap.vt, &inWrap.vt, &xzProps, progress ? &progressWrap.vt : NULL); + + RET_IF_WRAP_ERROR(inWrap.Res, res, SZ_ERROR_READ) + RET_IF_WRAP_ERROR(outWrap.Res, res, SZ_ERROR_WRITE) + RET_IF_WRAP_ERROR(progressWrap.Res, res, SZ_ERROR_PROGRESS) + + return SResToHRESULT(res); +} + +}} diff --git a/3rdparty/lzma/CPP/7zip/Compress/XzEncoder.h b/3rdparty/lzma/CPP/7zip/Compress/XzEncoder.h new file mode 100644 index 00000000000..434f582091e --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/Compress/XzEncoder.h @@ -0,0 +1,35 @@ +// XzEncoder.h + +#ifndef ZIP7_INC_XZ_ENCODER_H +#define ZIP7_INC_XZ_ENCODER_H + +#include "../../../C/XzEnc.h" + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +namespace NCompress { +namespace NXz { + +Z7_CLASS_IMP_COM_3( + CEncoder + , ICompressCoder + , ICompressSetCoderProperties + , ICompressSetCoderPropertiesOpt +) + CXzEncHandle _encoder; +public: + CXzProps xzProps; + + void InitCoderProps(); + HRESULT SetCheckSize(UInt32 checkSizeInBytes); + HRESULT SetCoderProp(PROPID propID, const PROPVARIANT &prop); + + CEncoder(); + ~CEncoder(); +}; + +}} + +#endif diff --git a/3rdparty/lzma/CPP/7zip/Crc.mak b/3rdparty/lzma/CPP/7zip/Crc.mak index f2b0874cb45..815142db856 100644 --- a/3rdparty/lzma/CPP/7zip/Crc.mak +++ b/3rdparty/lzma/CPP/7zip/Crc.mak @@ -1,6 +1,6 @@ C_OBJS = $(C_OBJS) \ $O\7zCrc.obj -!IF "$(CPU)" == "IA64" || "$(CPU)" == "MIPS" || "$(CPU)" == "ARM" +!IF "$(PLATFORM)" == "ia64" || "$(PLATFORM)" == "mips" || "$(PLATFORM)" == "arm" || "$(PLATFORM)" == "arm64" C_OBJS = $(C_OBJS) \ !ELSE ASM_OBJS = $(ASM_OBJS) \ diff --git a/3rdparty/lzma/CPP/7zip/Crc64.mak b/3rdparty/lzma/CPP/7zip/Crc64.mak index 57301c22345..d58a483261e 100644 --- a/3rdparty/lzma/CPP/7zip/Crc64.mak +++ b/3rdparty/lzma/CPP/7zip/Crc64.mak @@ -1,6 +1,6 @@ C_OBJS = $(C_OBJS) \ $O\XzCrc64.obj -!IF "$(CPU)" == "IA64" || "$(CPU)" == "MIPS" || "$(CPU)" == "ARM" +!IF "$(PLATFORM)" == "ia64" || "$(PLATFORM)" == "mips" || "$(PLATFORM)" == "arm" || "$(PLATFORM)" == "arm64" C_OBJS = $(C_OBJS) \ !ELSE ASM_OBJS = $(ASM_OBJS) \ diff --git a/3rdparty/lzma/CPP/7zip/Crypto/7zAes.cpp b/3rdparty/lzma/CPP/7zip/Crypto/7zAes.cpp index d33b562a3f6..6b1c648d5c1 100644 --- a/3rdparty/lzma/CPP/7zip/Crypto/7zAes.cpp +++ b/3rdparty/lzma/CPP/7zip/Crypto/7zAes.cpp @@ -2,11 +2,13 @@ #include "StdAfx.h" +#include "../../../C/CpuArch.h" #include "../../../C/Sha256.h" #include "../../Common/ComTry.h" +#include "../../Common/MyBuffer2.h" -#ifndef _7ZIP_ST +#ifndef Z7_ST #include "../../Windows/Synchronization.h" #endif @@ -15,7 +17,7 @@ #include "7zAes.h" #include "MyAes.h" -#ifndef EXTRACT_ONLY +#ifndef Z7_EXTRACT_ONLY #include "RandGen.h" #endif @@ -48,31 +50,65 @@ void CKeyInfo::CalcKey() } else { - size_t bufSize = 8 + SaltSize + Password.Size(); - CObjArray<Byte> buf(bufSize); + const unsigned kUnrPow = 6; + const UInt32 numUnroll = (UInt32)1 << (NumCyclesPower <= kUnrPow ? (unsigned)NumCyclesPower : kUnrPow); + + const size_t bufSize = 8 + SaltSize + Password.Size(); + const size_t unrollSize = bufSize * numUnroll; + + // MY_ALIGN (16) + // CSha256 sha; + CAlignedBuffer sha(sizeof(CSha256) + unrollSize + bufSize * 2); + Byte *buf = sha + sizeof(CSha256); + memcpy(buf, Salt, SaltSize); memcpy(buf + SaltSize, Password, Password.Size()); + memset(buf + bufSize - 8, 0, 8); - CSha256 sha; - Sha256_Init(&sha); - - Byte *ctr = buf + SaltSize + Password.Size(); - - for (unsigned i = 0; i < 8; i++) - ctr[i] = 0; + Sha256_Init((CSha256 *)(void *)(Byte *)sha); + { + { + Byte *dest = buf; + for (UInt32 i = 1; i < numUnroll; i++) + { + dest += bufSize; + memcpy(dest, buf, bufSize); + } + } + + const UInt32 numRounds = (UInt32)1 << NumCyclesPower; + UInt32 r = 0; + do + { + Byte *dest = buf + bufSize - 8; + UInt32 i = r; + r += numUnroll; + do + { + SetUi32(dest, i) i++; dest += bufSize; + // SetUi32(dest, i) i++; dest += bufSize; + } + while (i < r); + Sha256_Update((CSha256 *)(void *)(Byte *)sha, buf, unrollSize); + } + while (r < numRounds); + } + /* UInt64 numRounds = (UInt64)1 << NumCyclesPower; do { - Sha256_Update(&sha, buf, bufSize); + Sha256_Update((CSha256 *)(Byte *)sha, buf, bufSize); for (unsigned i = 0; i < 8; i++) if (++(ctr[i]) != 0) break; } while (--numRounds != 0); + */ - Sha256_Final(&sha, Key); + Sha256_Final((CSha256 *)(void *)(Byte *)sha, Key); + memset(sha, 0, sha.Size()); } } @@ -117,7 +153,7 @@ void CKeyInfoCache::Add(const CKeyInfo &key) static CKeyInfoCache g_GlobalKeyCache(32); -#ifndef _7ZIP_ST +#ifndef Z7_ST static NWindows::NSynchronization::CCriticalSection g_GlobalKeyCacheCriticalSection; #define MT_LOCK NWindows::NSynchronization::CCriticalSectionLock lock(g_GlobalKeyCacheCriticalSection); #else @@ -149,10 +185,10 @@ void CBase::PrepareKey() g_GlobalKeyCache.FindAndAdd(_key); } -#ifndef EXTRACT_ONLY +#ifndef Z7_EXTRACT_ONLY /* -STDMETHODIMP CEncoder::ResetSalt() +Z7_COM7F_IMF(CEncoder::ResetSalt()) { _key.SaltSize = 4; g_RandomGenerator.Generate(_key.Salt, _key.SaltSize); @@ -160,16 +196,16 @@ STDMETHODIMP CEncoder::ResetSalt() } */ -STDMETHODIMP CEncoder::ResetInitVector() +Z7_COM7F_IMF(CEncoder::ResetInitVector()) { for (unsigned i = 0; i < sizeof(_iv); i++) _iv[i] = 0; - _ivSize = 8; - g_RandomGenerator.Generate(_iv, _ivSize); + _ivSize = 16; + MY_RAND_GEN(_iv, _ivSize); return S_OK; } -STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) +Z7_COM7F_IMF(CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)) { Byte props[2 + sizeof(_key.Salt) + sizeof(_iv)]; unsigned propsSize = 1; @@ -207,7 +243,7 @@ CDecoder::CDecoder() _aesFilter = new CAesCbcDecoder(kKeySize); } -STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) +Z7_COM7F_IMF(CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)) { _key.ClearProps(); @@ -246,33 +282,34 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) } -STDMETHODIMP CBaseCoder::CryptoSetPassword(const Byte *data, UInt32 size) +Z7_COM7F_IMF(CBaseCoder::CryptoSetPassword(const Byte *data, UInt32 size)) { COM_TRY_BEGIN + _key.Password.Wipe(); _key.Password.CopyFrom(data, (size_t)size); return S_OK; COM_TRY_END } -STDMETHODIMP CBaseCoder::Init() +Z7_COM7F_IMF(CBaseCoder::Init()) { COM_TRY_BEGIN PrepareKey(); CMyComPtr<ICryptoProperties> cp; - RINOK(_aesFilter.QueryInterface(IID_ICryptoProperties, &cp)); + RINOK(_aesFilter.QueryInterface(IID_ICryptoProperties, &cp)) if (!cp) return E_FAIL; - RINOK(cp->SetKey(_key.Key, kKeySize)); - RINOK(cp->SetInitVector(_iv, sizeof(_iv))); + RINOK(cp->SetKey(_key.Key, kKeySize)) + RINOK(cp->SetInitVector(_iv, sizeof(_iv))) return _aesFilter->Init(); COM_TRY_END } -STDMETHODIMP_(UInt32) CBaseCoder::Filter(Byte *data, UInt32 size) +Z7_COM7F_IMF2(UInt32, CBaseCoder::Filter(Byte *data, UInt32 size)) { return _aesFilter->Filter(data, size); } diff --git a/3rdparty/lzma/CPP/7zip/Crypto/7zAes.h b/3rdparty/lzma/CPP/7zip/Crypto/7zAes.h index 84e07ac9613..8f7bf03eb29 100644 --- a/3rdparty/lzma/CPP/7zip/Crypto/7zAes.h +++ b/3rdparty/lzma/CPP/7zip/Crypto/7zAes.h @@ -1,7 +1,7 @@ // 7zAes.h -#ifndef __CRYPTO_7Z_AES_H -#define __CRYPTO_7Z_AES_H +#ifndef ZIP7_INC_CRYPTO_7Z_AES_H +#define ZIP7_INC_CRYPTO_7Z_AES_H #include "../../Common/MyBuffer.h" #include "../../Common/MyCom.h" @@ -37,6 +37,20 @@ public: for (unsigned i = 0; i < sizeof(Salt); i++) Salt[i] = 0; } + + void Wipe() + { + Password.Wipe(); + NumCyclesPower = 0; + SaltSize = 0; + Z7_memset_0_ARRAY(Salt); + Z7_memset_0_ARRAY(Key); + } + +#ifdef Z7_CPP_IS_SUPPORTED_default + CKeyInfo(const CKeyInfo &) = default; +#endif + ~CKeyInfo() { Wipe(); } }; class CKeyInfoCache @@ -68,48 +82,46 @@ class CBaseCoder: public CMyUnknownImp, public CBase { + Z7_IFACE_COM7_IMP(ICompressFilter) + Z7_IFACE_COM7_IMP(ICryptoSetPassword) protected: + virtual ~CBaseCoder() {} CMyComPtr<ICompressFilter> _aesFilter; - -public: - INTERFACE_ICompressFilter(;) - - STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size); }; -#ifndef EXTRACT_ONLY +#ifndef Z7_EXTRACT_ONLY -class CEncoder: +class CEncoder Z7_final: public CBaseCoder, public ICompressWriteCoderProperties, // public ICryptoResetSalt, public ICryptoResetInitVector { -public: - MY_UNKNOWN_IMP4( + Z7_COM_UNKNOWN_IMP_4( ICompressFilter, ICryptoSetPassword, ICompressWriteCoderProperties, // ICryptoResetSalt, ICryptoResetInitVector) - STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream); - // STDMETHOD(ResetSalt)(); - STDMETHOD(ResetInitVector)(); + Z7_IFACE_COM7_IMP(ICompressWriteCoderProperties) + // Z7_IFACE_COM7_IMP(ICryptoResetSalt) + Z7_IFACE_COM7_IMP(ICryptoResetInitVector) +public: CEncoder(); }; #endif -class CDecoder: +class CDecoder Z7_final: public CBaseCoder, public ICompressSetDecoderProperties2 { -public: - MY_UNKNOWN_IMP3( + Z7_COM_UNKNOWN_IMP_3( ICompressFilter, ICryptoSetPassword, ICompressSetDecoderProperties2) - STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); + Z7_IFACE_COM7_IMP(ICompressSetDecoderProperties2) +public: CDecoder(); }; diff --git a/3rdparty/lzma/CPP/7zip/Crypto/7zAesRegister.cpp b/3rdparty/lzma/CPP/7zip/Crypto/7zAesRegister.cpp index f9d59699b7c..69d0890a40b 100644 --- a/3rdparty/lzma/CPP/7zip/Crypto/7zAesRegister.cpp +++ b/3rdparty/lzma/CPP/7zip/Crypto/7zAesRegister.cpp @@ -9,9 +9,9 @@ namespace NCrypto { namespace N7z { -REGISTER_FILTER_E(7zAES, - CDecoder(), - CEncoder(), +REGISTER_FILTER_E(SzAES, + CDecoder, + CEncoder, 0x6F10701, "7zAES") }} diff --git a/3rdparty/lzma/CPP/7zip/Crypto/MyAes.cpp b/3rdparty/lzma/CPP/7zip/Crypto/MyAes.cpp index 52eaab7ae2c..6abc38812b3 100644 --- a/3rdparty/lzma/CPP/7zip/Crypto/MyAes.cpp +++ b/3rdparty/lzma/CPP/7zip/Crypto/MyAes.cpp @@ -10,103 +10,237 @@ namespace NCrypto { static struct CAesTabInit { CAesTabInit() { AesGenTables();} } g_AesTabInit; -CAesCbcCoder::CAesCbcCoder(bool encodeMode, unsigned keySize): - _keySize(keySize), +CAesCoder::CAesCoder( + // bool encodeMode, + unsigned keySize + // , bool ctrMode + ): _keyIsSet(false), - _encodeMode(encodeMode) + // _encodeMode(encodeMode), + // _ctrMode(ctrMode), + _keySize(keySize), + // _ctrPos(0), // _ctrPos =0 will be set in Init() + _aes(AES_NUM_IVMRK_WORDS * 4 + AES_BLOCK_SIZE * 2) { - _offset = ((0 - (unsigned)(ptrdiff_t)_aes) & 0xF) / sizeof(UInt32); + // _offset = ((0 - (unsigned)(ptrdiff_t)_aes) & 0xF) / sizeof(UInt32); memset(_iv, 0, AES_BLOCK_SIZE); - SetFunctions(0); + /* + // we can use the following code to test 32-bit overflow case for AES-CTR + for (unsigned i = 0; i < 16; i++) _iv[i] = (Byte)(i + 1); + _iv[0] = 0xFE; _iv[1] = _iv[2] = _iv[3] = 0xFF; + */ } -STDMETHODIMP CAesCbcCoder::Init() +Z7_COM7F_IMF(CAesCoder::Init()) { - AesCbc_Init(_aes + _offset, _iv); - return _keyIsSet ? S_OK : E_FAIL; + _ctrPos = 0; + AesCbc_Init(Aes(), _iv); + return _keyIsSet ? S_OK : E_NOTIMPL; // E_FAIL } -STDMETHODIMP_(UInt32) CAesCbcCoder::Filter(Byte *data, UInt32 size) +Z7_COM7F_IMF2(UInt32, CAesCoder::Filter(Byte *data, UInt32 size)) { if (!_keyIsSet) return 0; - if (size == 0) - return 0; if (size < AES_BLOCK_SIZE) + { + if (size == 0) + return 0; return AES_BLOCK_SIZE; + } size >>= 4; - _codeFunc(_aes + _offset, data, size); + // (data) must be aligned for 16-bytes here + _codeFunc(Aes(), data, size); return size << 4; } -STDMETHODIMP CAesCbcCoder::SetKey(const Byte *data, UInt32 size) + +Z7_COM7F_IMF(CAesCoder::SetKey(const Byte *data, UInt32 size)) { if ((size & 0x7) != 0 || size < 16 || size > 32) return E_INVALIDARG; if (_keySize != 0 && size != _keySize) return E_INVALIDARG; - AES_SET_KEY_FUNC setKeyFunc = _encodeMode ? Aes_SetKey_Enc : Aes_SetKey_Dec; - setKeyFunc(_aes + _offset + 4, data, size); + _setKeyFunc(Aes() + 4, data, size); _keyIsSet = true; return S_OK; } -STDMETHODIMP CAesCbcCoder::SetInitVector(const Byte *data, UInt32 size) +Z7_COM7F_IMF(CAesCoder::SetInitVector(const Byte *data, UInt32 size)) { if (size != AES_BLOCK_SIZE) return E_INVALIDARG; memcpy(_iv, data, size); - CAesCbcCoder::Init(); // don't call virtual function here !!! + /* we allow SetInitVector() call before SetKey() call. + so we ignore possible error in Init() here */ + CAesCoder::Init(); // don't call virtual function here !!! return S_OK; } -EXTERN_C_BEGIN -void MY_FAST_CALL AesCbc_Encode(UInt32 *ivAes, Byte *data, size_t numBlocks); -void MY_FAST_CALL AesCbc_Decode(UInt32 *ivAes, Byte *data, size_t numBlocks); -void MY_FAST_CALL AesCtr_Code(UInt32 *ivAes, Byte *data, size_t numBlocks); +#ifndef Z7_SFX -void MY_FAST_CALL AesCbc_Encode_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks); -void MY_FAST_CALL AesCbc_Decode_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks); -void MY_FAST_CALL AesCtr_Code_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks); - -EXTERN_C_END +/* +Z7_COM7F_IMF(CAesCtrCoder::Init()) +{ + _ctrPos = 0; + return CAesCoder::Init(); +} +*/ -bool CAesCbcCoder::SetFunctions(UInt32 algo) +Z7_COM7F_IMF2(UInt32, CAesCtrCoder::Filter(Byte *data, UInt32 size)) { - _codeFunc = _encodeMode ? - g_AesCbc_Encode : - g_AesCbc_Decode; - if (algo == 1) + if (!_keyIsSet) + return 0; + if (size == 0) + return 0; + + if (_ctrPos != 0) { - _codeFunc = _encodeMode ? - AesCbc_Encode: - AesCbc_Decode; + /* Optimized caller will not call here */ + const Byte *ctr = (Byte *)(Aes() + AES_NUM_IVMRK_WORDS); + unsigned num = 0; + for (unsigned i = _ctrPos; i != AES_BLOCK_SIZE; i++) + { + if (num == size) + { + _ctrPos = i; + return num; + } + data[num++] ^= ctr[i]; + } + _ctrPos = 0; + /* if (num < size) { + we can filter more data with _codeFunc(). + But it's supposed that the caller can work correctly, + even if we do only partial filtering here. + So we filter data only for current 16-byte block. } + */ + /* + size -= num; + size >>= 4; + // (data) must be aligned for 16-bytes here + _codeFunc(Aes(), data + num, size); + return num + (size << 4); + */ + return num; } - if (algo == 2) + + if (size < AES_BLOCK_SIZE) { - #ifdef MY_CPU_X86_OR_AMD64 - if (g_AesCbc_Encode != AesCbc_Encode_Intel) - #endif - return false; + /* The good optimized caller can call here only in last Filter() call. + But we support also non-optimized callers, + where another Filter() calls are allowed after this call. + */ + Byte *ctr = (Byte *)(Aes() + AES_NUM_IVMRK_WORDS); + memset(ctr, 0, AES_BLOCK_SIZE); + memcpy(ctr, data, size); + _codeFunc(Aes(), ctr, 1); + memcpy(data, ctr, size); + _ctrPos = size; + return size; } - return true; + + size >>= 4; + // (data) must be aligned for 16-bytes here + _codeFunc(Aes(), data, size); + return size << 4; } -STDMETHODIMP CAesCbcCoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps) +#endif // Z7_SFX + + +#ifndef Z7_EXTRACT_ONLY + +#ifdef MY_CPU_X86_OR_AMD64 + #define USE_HW_AES +#elif defined(MY_CPU_ARM_OR_ARM64) && defined(MY_CPU_LE) + #if defined(__clang__) + #if (__clang_major__ >= 8) // fix that check + #define USE_HW_AES + #endif + #elif defined(__GNUC__) + #if (__GNUC__ >= 6) // fix that check + #define USE_HW_AES + #endif + #elif defined(_MSC_VER) + #if _MSC_VER >= 1910 + #define USE_HW_AES + #endif + #endif +#endif + +#ifdef USE_HW_AES + #define SET_AES_FUNC_2(f2) \ + if (algo == 2) if (g_Aes_SupportedFunctions_Flags & k_Aes_SupportedFunctions_HW) \ + { f = f2; } + #ifdef MY_CPU_X86_OR_AMD64 + #define SET_AES_FUNC_23(f2, f3) \ + SET_AES_FUNC_2(f2) \ + if (algo == 3) if (g_Aes_SupportedFunctions_Flags & k_Aes_SupportedFunctions_HW_256) \ + { f = f3; } + #else // MY_CPU_X86_OR_AMD64 + #define SET_AES_FUNC_23(f2, f3) \ + SET_AES_FUNC_2(f2) + #endif // MY_CPU_X86_OR_AMD64 +#else // USE_HW_AES + #define SET_AES_FUNC_23(f2, f3) +#endif // USE_HW_AES + +#define SET_AES_FUNCS(c, f0, f1, f2, f3) \ + bool c::SetFunctions(UInt32 algo) { \ + _codeFunc = f0; if (algo < 1) return true; \ + AES_CODE_FUNC f = NULL; \ + if (algo == 1) { f = f1; } \ + SET_AES_FUNC_23(f2, f3) \ + if (f) { _codeFunc = f; return true; } \ + return false; } + + + +#ifndef Z7_SFX +SET_AES_FUNCS( + CAesCtrCoder, + g_AesCtr_Code, + AesCtr_Code, + AesCtr_Code_HW, + AesCtr_Code_HW_256) +#endif + +SET_AES_FUNCS( + CAesCbcEncoder, + g_AesCbc_Encode, + AesCbc_Encode, + AesCbc_Encode_HW, + AesCbc_Encode_HW) + +SET_AES_FUNCS( + CAesCbcDecoder, + g_AesCbc_Decode, + AesCbc_Decode, + AesCbc_Decode_HW, + AesCbc_Decode_HW_256) + +Z7_COM7F_IMF(CAesCoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps)) { + UInt32 algo = 0; for (UInt32 i = 0; i < numProps; i++) { - const PROPVARIANT &prop = coderProps[i]; if (propIDs[i] == NCoderPropID::kDefaultProp) { + const PROPVARIANT &prop = coderProps[i]; if (prop.vt != VT_UI4) return E_INVALIDARG; - if (!SetFunctions(prop.ulVal)) + if (prop.ulVal > 3) return E_NOTIMPL; + algo = prop.ulVal; } } + if (!SetFunctions(algo)) + return E_NOTIMPL; return S_OK; } +#endif // Z7_EXTRACT_ONLY + } diff --git a/3rdparty/lzma/CPP/7zip/Crypto/MyAes.h b/3rdparty/lzma/CPP/7zip/Crypto/MyAes.h index 84c21de30e7..a3c1c27faa5 100644 --- a/3rdparty/lzma/CPP/7zip/Crypto/MyAes.h +++ b/3rdparty/lzma/CPP/7zip/Crypto/MyAes.h @@ -1,55 +1,122 @@ // Crypto/MyAes.h -#ifndef __CRYPTO_MY_AES_H -#define __CRYPTO_MY_AES_H +#ifndef ZIP7_INC_CRYPTO_MY_AES_H +#define ZIP7_INC_CRYPTO_MY_AES_H #include "../../../C/Aes.h" +#include "../../Common/MyBuffer2.h" #include "../../Common/MyCom.h" #include "../ICoder.h" namespace NCrypto { -class CAesCbcCoder: +#ifdef Z7_EXTRACT_ONLY +#define Z7_IFACEN_IAesCoderSetFunctions(x) +#else +#define Z7_IFACEN_IAesCoderSetFunctions(x) \ + virtual bool SetFunctions(UInt32 algo) x +#endif + + +class CAesCoder: public ICompressFilter, public ICryptoProperties, + #ifndef Z7_EXTRACT_ONLY public ICompressSetCoderProperties, + #endif public CMyUnknownImp { - AES_CODE_FUNC _codeFunc; - unsigned _offset; - unsigned _keySize; + Z7_COM_QI_BEGIN2(ICompressFilter) + Z7_COM_QI_ENTRY(ICryptoProperties) + #ifndef Z7_EXTRACT_ONLY + Z7_COM_QI_ENTRY(ICompressSetCoderProperties) + #endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + +public: + Z7_IFACE_COM7_IMP_NONFINAL(ICompressFilter) + Z7_IFACE_COM7_IMP(ICryptoProperties) +private: + #ifndef Z7_EXTRACT_ONLY + Z7_IFACE_COM7_IMP(ICompressSetCoderProperties) + #endif + +protected: bool _keyIsSet; - bool _encodeMode; - UInt32 _aes[AES_NUM_IVMRK_WORDS + 3]; + // bool _encodeMode; + // bool _ctrMode; + // unsigned _offset; + unsigned _keySize; + unsigned _ctrPos; // we need _ctrPos here for Init() / SetInitVector() + AES_CODE_FUNC _codeFunc; + AES_SET_KEY_FUNC _setKeyFunc; +private: + // UInt32 _aes[AES_NUM_IVMRK_WORDS + 3]; + CAlignedBuffer1 _aes; + Byte _iv[AES_BLOCK_SIZE]; - bool SetFunctions(UInt32 algo); + // UInt32 *Aes() { return _aes + _offset; } +protected: + UInt32 *Aes() { return (UInt32 *)(void *)(Byte *)_aes; } + + Z7_IFACE_PURE(IAesCoderSetFunctions) public: - CAesCbcCoder(bool encodeMode, unsigned keySize); - - MY_UNKNOWN_IMP3(ICompressFilter, ICryptoProperties, ICompressSetCoderProperties) - - INTERFACE_ICompressFilter(;) - - STDMETHOD(SetKey)(const Byte *data, UInt32 size); - STDMETHOD(SetInitVector)(const Byte *data, UInt32 size); - - STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); + CAesCoder( + // bool encodeMode, + unsigned keySize + // , bool ctrMode + ); + virtual ~CAesCoder() {} // we need virtual destructor for derived classes + void SetKeySize(unsigned size) { _keySize = size; } }; -struct CAesCbcEncoder: public CAesCbcCoder + +#ifndef Z7_EXTRACT_ONLY +struct CAesCbcEncoder: public CAesCoder { - CAesCbcEncoder(unsigned keySize = 0): CAesCbcCoder(true, keySize) {} + CAesCbcEncoder(unsigned keySize = 0): CAesCoder(keySize) + { + _setKeyFunc = Aes_SetKey_Enc; + _codeFunc = g_AesCbc_Encode; + } + Z7_IFACE_IMP(IAesCoderSetFunctions) }; +#endif -struct CAesCbcDecoder: public CAesCbcCoder +struct CAesCbcDecoder: public CAesCoder { - CAesCbcDecoder(unsigned keySize = 0): CAesCbcCoder(false, keySize) {} + CAesCbcDecoder(unsigned keySize = 0): CAesCoder(keySize) + { + _setKeyFunc = Aes_SetKey_Dec; + _codeFunc = g_AesCbc_Decode; + } + Z7_IFACE_IMP(IAesCoderSetFunctions) }; +#ifndef Z7_SFX +struct CAesCtrCoder: public CAesCoder +{ +private: + // unsigned _ctrPos; + // Z7_IFACE_COM7_IMP(ICompressFilter) + // Z7_COM7F_IMP(Init()) + Z7_COM7F_IMP2(UInt32, Filter(Byte *data, UInt32 size)) +public: + CAesCtrCoder(unsigned keySize = 0): CAesCoder(keySize) + { + _ctrPos = 0; + _setKeyFunc = Aes_SetKey_Enc; + _codeFunc = g_AesCtr_Code; + } + Z7_IFACE_IMP(IAesCoderSetFunctions) +}; +#endif + } #endif diff --git a/3rdparty/lzma/CPP/7zip/Crypto/MyAesReg.cpp b/3rdparty/lzma/CPP/7zip/Crypto/MyAesReg.cpp index 28006835549..e2b4f72dbdc 100644 --- a/3rdparty/lzma/CPP/7zip/Crypto/MyAesReg.cpp +++ b/3rdparty/lzma/CPP/7zip/Crypto/MyAesReg.cpp @@ -8,9 +8,22 @@ namespace NCrypto { -REGISTER_FILTER_E(AES256CBC, - CAesCbcDecoder(32), - CAesCbcEncoder(32), - 0x6F00181, "AES256CBC") +#ifndef Z7_SFX + +#define REGISTER_AES_2(name, nameString, keySize) \ + REGISTER_FILTER_E(name, \ + CAesCbcDecoder(keySize), \ + CAesCbcEncoder(keySize), \ + 0x6F00100 | ((keySize - 16) * 8) | (/* isCtr */ 0 ? 4 : 1), \ + nameString) \ + +#define REGISTER_AES(name, nameString) \ + /* REGISTER_AES_2(AES128 ## name, "AES128" nameString, 16) */ \ + /* REGISTER_AES_2(AES192 ## name, "AES192" nameString, 24) */ \ + REGISTER_AES_2(AES256 ## name, "AES256" nameString, 32) \ + +REGISTER_AES(CBC, "CBC") + +#endif } diff --git a/3rdparty/lzma/CPP/7zip/Crypto/RandGen.cpp b/3rdparty/lzma/CPP/7zip/Crypto/RandGen.cpp index 408f73f1686..05a6c06d4c3 100644 --- a/3rdparty/lzma/CPP/7zip/Crypto/RandGen.cpp +++ b/3rdparty/lzma/CPP/7zip/Crypto/RandGen.cpp @@ -2,14 +2,44 @@ #include "StdAfx.h" -#ifndef _7ZIP_ST +#include "RandGen.h" + +#ifndef USE_STATIC_SYSTEM_RAND + +#ifndef Z7_ST #include "../../Windows/Synchronization.h" #endif -#include "RandGen.h" -#ifndef _WIN32 +#ifdef _WIN32 + +#ifdef _WIN64 +#define USE_STATIC_RtlGenRandom +#endif + +#ifdef USE_STATIC_RtlGenRandom + +// #include <NTSecAPI.h> + +EXTERN_C_BEGIN +#ifndef RtlGenRandom + #define RtlGenRandom SystemFunction036 + BOOLEAN WINAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength); +#endif +EXTERN_C_END + +#else +EXTERN_C_BEGIN +typedef BOOLEAN (WINAPI * Func_RtlGenRandom)(PVOID RandomBuffer, ULONG RandomBufferLength); +EXTERN_C_END +#endif + + +#else #include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> #define USE_POSIX_TIME #define USE_POSIX_TIME2 #endif @@ -21,61 +51,141 @@ #endif #endif -// This is not very good random number generator. -// Please use it only for salt. -// First generated data block depends from timer and processID. +// The seed and first generated data block depend from processID, +// theadID, timer and system random generator, if available. // Other generated data blocks depend from previous state -// Maybe it's possible to restore original timer value from generated value. #define HASH_UPD(x) Sha256_Update(&hash, (const Byte *)&x, sizeof(x)); void CRandomGenerator::Init() { + MY_ALIGN (16) CSha256 hash; Sha256_Init(&hash); + unsigned numIterations = 1000; + + { + #ifndef UNDER_CE + const unsigned kNumIterations_Small = 100; + const unsigned kBufSize = 32; + MY_ALIGN (16) + Byte buf[kBufSize]; + #endif + #ifdef _WIN32 + DWORD w = ::GetCurrentProcessId(); - HASH_UPD(w); + HASH_UPD(w) w = ::GetCurrentThreadId(); - HASH_UPD(w); + HASH_UPD(w) + + #ifdef UNDER_CE + /* + if (CeGenRandom(kBufSize, buf)) + { + numIterations = kNumIterations_Small; + Sha256_Update(&hash, buf, kBufSize); + } + */ + #elif defined(USE_STATIC_RtlGenRandom) + if (RtlGenRandom(buf, kBufSize)) + { + numIterations = kNumIterations_Small; + Sha256_Update(&hash, buf, kBufSize); + } #else + { + const HMODULE hModule = ::LoadLibrary(TEXT("advapi32.dll")); + if (hModule) + { + // SystemFunction036() is real name of RtlGenRandom() function + const + Func_RtlGenRandom + my_RtlGenRandom = Z7_GET_PROC_ADDRESS( + Func_RtlGenRandom, hModule, "SystemFunction036"); + if (my_RtlGenRandom) + { + if (my_RtlGenRandom(buf, kBufSize)) + { + numIterations = kNumIterations_Small; + Sha256_Update(&hash, buf, kBufSize); + } + } + ::FreeLibrary(hModule); + } + } + #endif + + #else + pid_t pid = getpid(); - HASH_UPD(pid); + HASH_UPD(pid) pid = getppid(); - HASH_UPD(pid); + HASH_UPD(pid) + + { + int f = open("/dev/urandom", O_RDONLY); + unsigned numBytes = kBufSize; + if (f >= 0) + { + do + { + ssize_t n = read(f, buf, numBytes); + if (n <= 0) + break; + Sha256_Update(&hash, buf, (size_t)n); + numBytes -= (unsigned)n; + } + while (numBytes); + close(f); + if (numBytes == 0) + numIterations = kNumIterations_Small; + } + } + /* + { + int n = getrandom(buf, kBufSize, 0); + if (n > 0) + { + Sha256_Update(&hash, buf, n); + if (n == kBufSize) + numIterations = kNumIterations_Small; + } + } + */ + + #endif + } + + #ifdef _DEBUG + numIterations = 2; #endif - for (unsigned i = 0; i < - #ifdef _DEBUG - 2; - #else - 1000; - #endif - i++) + do { #ifdef _WIN32 LARGE_INTEGER v; if (::QueryPerformanceCounter(&v)) - HASH_UPD(v.QuadPart); + HASH_UPD(v.QuadPart) #endif #ifdef USE_POSIX_TIME #ifdef USE_POSIX_TIME2 timeval v; - if (gettimeofday(&v, 0) == 0) + if (gettimeofday(&v, NULL) == 0) { - HASH_UPD(v.tv_sec); - HASH_UPD(v.tv_usec); + HASH_UPD(v.tv_sec) + HASH_UPD(v.tv_usec) } #endif - time_t v2 = time(NULL); - HASH_UPD(v2); + const time_t v2 = time(NULL); + HASH_UPD(v2) #endif #ifdef _WIN32 - DWORD tickCount = ::GetTickCount(); - HASH_UPD(tickCount); + const DWORD tickCount = ::GetTickCount(); + HASH_UPD(tickCount) #endif for (unsigned j = 0; j < 100; j++) @@ -85,11 +195,13 @@ void CRandomGenerator::Init() Sha256_Update(&hash, _buff, SHA256_DIGEST_SIZE); } } + while (--numIterations); + Sha256_Final(&hash, _buff); _needInit = false; } -#ifndef _7ZIP_ST +#ifndef Z7_ST static NWindows::NSynchronization::CCriticalSection g_CriticalSection; #define MT_LOCK NWindows::NSynchronization::CCriticalSectionLock lock(g_CriticalSection); #else @@ -104,6 +216,7 @@ void CRandomGenerator::Generate(Byte *data, unsigned size) Init(); while (size != 0) { + MY_ALIGN (16) CSha256 hash; Sha256_Init(&hash); @@ -112,8 +225,9 @@ void CRandomGenerator::Generate(Byte *data, unsigned size) Sha256_Init(&hash); UInt32 salt = 0xF672ABD1; - HASH_UPD(salt); + HASH_UPD(salt) Sha256_Update(&hash, _buff, SHA256_DIGEST_SIZE); + MY_ALIGN (16) Byte buff[SHA256_DIGEST_SIZE]; Sha256_Final(&hash, buff); for (unsigned i = 0; i < SHA256_DIGEST_SIZE && size != 0; i++, size--) @@ -121,4 +235,7 @@ void CRandomGenerator::Generate(Byte *data, unsigned size) } } +MY_ALIGN (16) CRandomGenerator g_RandomGenerator; + +#endif diff --git a/3rdparty/lzma/CPP/7zip/Crypto/RandGen.h b/3rdparty/lzma/CPP/7zip/Crypto/RandGen.h index cfdcd60d012..3bd69ec2d16 100644 --- a/3rdparty/lzma/CPP/7zip/Crypto/RandGen.h +++ b/3rdparty/lzma/CPP/7zip/Crypto/RandGen.h @@ -1,10 +1,25 @@ // RandGen.h -#ifndef __CRYPTO_RAND_GEN_H -#define __CRYPTO_RAND_GEN_H +#ifndef ZIP7_INC_CRYPTO_RAND_GEN_H +#define ZIP7_INC_CRYPTO_RAND_GEN_H #include "../../../C/Sha256.h" +#ifdef _WIN64 +// #define USE_STATIC_SYSTEM_RAND +#endif + +#ifdef USE_STATIC_SYSTEM_RAND + +#ifdef _WIN32 +#include <ntsecapi.h> +#define MY_RAND_GEN(data, size) RtlGenRandom(data, size) +#else +#define MY_RAND_GEN(data, size) getrandom(data, size, 0) +#endif + +#else + class CRandomGenerator { Byte _buff[SHA256_DIGEST_SIZE]; @@ -12,10 +27,15 @@ class CRandomGenerator void Init(); public: - CRandomGenerator(): _needInit(true) {}; + CRandomGenerator(): _needInit(true) {} void Generate(Byte *data, unsigned size); }; +MY_ALIGN (16) extern CRandomGenerator g_RandomGenerator; +#define MY_RAND_GEN(data, size) g_RandomGenerator.Generate(data, size) + +#endif + #endif diff --git a/3rdparty/lzma/CPP/7zip/Crypto/StdAfx.h b/3rdparty/lzma/CPP/7zip/Crypto/StdAfx.h index 1cbd7feaeec..80866550d1f 100644 --- a/3rdparty/lzma/CPP/7zip/Crypto/StdAfx.h +++ b/3rdparty/lzma/CPP/7zip/Crypto/StdAfx.h @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../Common/Common.h" #endif diff --git a/3rdparty/lzma/CPP/7zip/GuiCommon.rc b/3rdparty/lzma/CPP/7zip/GuiCommon.rc index 6b26ddd85c9..b67409b922f 100644 --- a/3rdparty/lzma/CPP/7zip/GuiCommon.rc +++ b/3rdparty/lzma/CPP/7zip/GuiCommon.rc @@ -71,6 +71,9 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US DEFPUSHBUTTON "OK", IDOK, bx2, by, bxs, bys \ PUSHBUTTON "Cancel", IDCANCEL, bx1, by, bxs, bys +#define MY_BUTTON__CLOSE \ + DEFPUSHBUTTON "&Close", IDCLOSE, bx1, by, bxs, bys + #define MY_COMBO CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP #define MY_COMBO_SORTED MY_COMBO | CBS_SORT diff --git a/3rdparty/lzma/CPP/7zip/Guid.txt b/3rdparty/lzma/CPP/7zip/Guid.txt index 7edab6ead87..eee28f731e9 100644 --- a/3rdparty/lzma/CPP/7zip/Guid.txt +++ b/3rdparty/lzma/CPP/7zip/Guid.txt @@ -19,9 +19,11 @@ 0F IOutFolderArchive 10 IFolderArchiveUpdateCallback2 11 IFolderScanProgress + 12 IFolderSetZoneIdMode 20 IFileExtractCallback.h::IGetProp - 30 IFileExtractCallback.h::IFolderExtractToStreamCallback + 30 IFileExtractCallback.h::IFolderExtractToStreamCallback (old) + 31 IFileExtractCallback.h::IFolderExtractToStreamCallback (new 21.04) 03 IStream.h @@ -29,10 +31,14 @@ 02 ISequentialOutStream 03 IInStream 04 IOutStream + 06 IStreamGetSize 07 IOutStreamFinish 08 IStreamGetProps 09 IStreamGetProps2 + 0A IStreamGetProp + + 10 IStreamSetRestriction 04 ICoder.h @@ -40,6 +46,7 @@ 04 ICompressProgressInfo 05 ICompressCoder 18 ICompressCoder2 + 1F ICompressSetCoderPropertiesOpt 20 ICompressSetCoderProperties 21 ICompressSetDecoderProperties // 22 ICompressSetDecoderProperties2 @@ -47,6 +54,9 @@ 24 ICompressGetInStreamProcessedSize 25 ICompressSetCoderMt 26 ICompressSetFinishMode + 27 ICompressGetInStreamProcessedSize2 + 28 ICompressSetMemLimit + 29 ICompressReadUnusedFromInBuf 30 ICompressGetSubStreamSize 31 ICompressSetInStream @@ -87,7 +97,8 @@ 10 IArchiveOpenCallback 20 IArchiveExtractCallback - 21 IArchiveExtractCallbackMessage + 21 IArchiveExtractCallbackMessage (deprecated in v23) + 22 IArchiveExtractCallbackMessage2 (new in v23) 30 IArchiveOpenVolumeCallback 40 IInArchiveGetStream @@ -100,6 +111,9 @@ 80 IArchiveUpdateCallback 82 IArchiveUpdateCallback2 83 IArchiveUpdateCallbackFile + 84 IArchiveGetDiskProperty + 85 IArchiveUpdateCallbackArcProp (Reserved) + A0 IOutArchive @@ -163,6 +177,13 @@ Handler GUIDs: 0C xz 0D ppmd + C0 AVB + C1 LP + C2 Sparse + C3 APFS + C4 Vhdx + C5 Base64 + C6 COFF C7 Ext C8 VMDK C9 VDI diff --git a/3rdparty/lzma/CPP/7zip/ICoder.h b/3rdparty/lzma/CPP/7zip/ICoder.h index 75db9399379..aec2834ad09 100644 --- a/3rdparty/lzma/CPP/7zip/ICoder.h +++ b/3rdparty/lzma/CPP/7zip/ICoder.h @@ -1,39 +1,40 @@ // ICoder.h -#ifndef __ICODER_H -#define __ICODER_H +#ifndef ZIP7_INC_ICODER_H +#define ZIP7_INC_ICODER_H #include "IStream.h" -#define CODER_INTERFACE(i, x) DECL_INTERFACE(i, 4, x) +Z7_PURE_INTERFACES_BEGIN -CODER_INTERFACE(ICompressProgressInfo, 0x04) -{ - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize) PURE; - - /* (inSize) can be NULL, if unknown - (outSize) can be NULL, if unknown +#define Z7_IFACE_CONSTR_CODER(i, n) \ + Z7_DECL_IFACE_7ZIP(i, 4, n) \ + { Z7_IFACE_COM7_PURE(i) }; +#define Z7_IFACEM_ICompressProgressInfo(x) \ + x(SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)) +Z7_IFACE_CONSTR_CODER(ICompressProgressInfo, 0x04) + /* + SetRatioInfo() + (inSize) can be NULL, if unknown + (outSize) can be NULL, if unknown returns: S_OK E_ABORT : Break by user another error codes */ -}; -CODER_INTERFACE(ICompressCoder, 0x05) -{ - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, - ICompressProgressInfo *progress) PURE; -}; +#define Z7_IFACEM_ICompressCoder(x) \ + x(Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, \ + const UInt64 *inSize, const UInt64 *outSize, \ + ICompressProgressInfo *progress)) +Z7_IFACE_CONSTR_CODER(ICompressCoder, 0x05) -CODER_INTERFACE(ICompressCoder2, 0x18) -{ - STDMETHOD(Code)(ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams, - ISequentialOutStream * const *outStreams, const UInt64 * const *outSizes, UInt32 numOutStreams, - ICompressProgressInfo *progress) PURE; -}; +#define Z7_IFACEM_ICompressCoder2(x) \ + x(Code(ISequentialInStream * const *inStreams, const UInt64 *const *inSizes, UInt32 numInStreams, \ + ISequentialOutStream *const *outStreams, const UInt64 *const *outSizes, UInt32 numOutStreams, \ + ICompressProgressInfo *progress)) +Z7_IFACE_CONSTR_CODER(ICompressCoder2, 0x18) /* ICompressCoder::Code @@ -43,6 +44,7 @@ CODER_INTERFACE(ICompressCoder2, 0x18) S_OK : OK S_FALSE : data error (for decoders) E_OUTOFMEMORY : memory allocation error + E_NOTIMPL : unsupported encoding method (for decoders) another error code : some error. For example, it can be error code received from inStream or outStream function. Parameters: @@ -53,7 +55,7 @@ CODER_INTERFACE(ICompressCoder2, 0x18) { Encoders in 7-Zip ignore (inSize). Decoder can use (*inSize) to check that stream was decoded correctly. - Some decoder in 7-Zip check it, if (full_decoding mode was set via ICompressSetFinishMode) + Some decoders in 7-Zip check it, if (full_decoding mode was set via ICompressSetFinishMode) } If it's required to limit the reading from input stream (inStream), it can @@ -104,82 +106,141 @@ namespace NCoderPropID enum EEnum { kDefaultProp = 0, - kDictionarySize, - kUsedMemorySize, - kOrder, - kBlockSize, - kPosStateBits, - kLitContextBits, - kLitPosBits, - kNumFastBytes, - kMatchFinder, - kMatchFinderCycles, - kNumPasses, - kAlgorithm, - kNumThreads, - kEndMarker, - kLevel, - kReduceSize // estimated size of data that will be compressed. Encoder can use this value to reduce dictionary size. + kDictionarySize, // VT_UI4 + kUsedMemorySize, // VT_UI4 + kOrder, // VT_UI4 + kBlockSize, // VT_UI4 or VT_UI8 + kPosStateBits, // VT_UI4 + kLitContextBits, // VT_UI4 + kLitPosBits, // VT_UI4 + kNumFastBytes, // VT_UI4 + kMatchFinder, // VT_BSTR + kMatchFinderCycles, // VT_UI4 + kNumPasses, // VT_UI4 + kAlgorithm, // VT_UI4 + kNumThreads, // VT_UI4 + kEndMarker, // VT_BOOL + kLevel, // VT_UI4 + kReduceSize, // VT_UI8 : it's estimated size of largest data stream that will be compressed + // encoder can use this value to reduce dictionary size and allocate data buffers + + kExpectedDataSize, // VT_UI8 : for ICompressSetCoderPropertiesOpt : + // it's estimated size of current data stream + // real data size can differ from that size + // encoder can use this value to optimize encoder initialization + + kBlockSize2, // VT_UI4 or VT_UI8 + kCheckSize, // VT_UI4 : size of digest in bytes + kFilter, // VT_BSTR + kMemUse, // VT_UI8 + kAffinity, // VT_UI8 + kBranchOffset, // VT_UI4 + kHashBits, // VT_UI4 + /* + // kHash3Bits, // VT_UI4 + // kHash2Bits, // VT_UI4 + // kChainBits, // VT_UI4 + kChainSize, // VT_UI4 + kNativeLevel, // VT_UI4 + kFast, // VT_UI4 + kMinMatch, // VT_UI4 The minimum slen is 3 and the maximum is 7. + kOverlapLog, // VT_UI4 The minimum ovlog is 0 and the maximum is 9. (default: 6) + kRowMatchFinder, // VT_BOOL + kLdmEnable, // VT_BOOL + // kLdmWindowSizeLog, // VT_UI4 + kLdmWindowSize, // VT_UI4 + kLdmHashLog, // VT_UI4 The minimum ldmhlog is 6 and the maximum is 26 (default: 20). + kLdmMinMatchLength, // VT_UI4 The minimum ldmslen is 4 and the maximum is 4096 (default: 64). + kLdmBucketSizeLog, // VT_UI4 The minimum ldmblog is 0 and the maximum is 8 (default: 3). + kLdmHashRateLog, // VT_UI4 The default value is wlog - ldmhlog. + kWriteUnpackSizeFlag, // VT_BOOL + kUsePledged, // VT_BOOL + kUseSizeHintPledgedForSmall, // VT_BOOL + kUseSizeHintForEach, // VT_BOOL + kUseSizeHintGlobal, // VT_BOOL + kParamSelectMode, // VT_UI4 + // kSearchLog, // VT_UI4 The minimum slog is 1 and the maximum is 26 + // kTargetLen, // VT_UI4 The minimum tlen is 0 and the maximum is 999. + */ + k_NUM_DEFINED }; } -CODER_INTERFACE(ICompressSetCoderProperties, 0x20) -{ - STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps) PURE; -}; +#define Z7_IFACEM_ICompressSetCoderPropertiesOpt(x) \ + x(SetCoderPropertiesOpt(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)) +Z7_IFACE_CONSTR_CODER(ICompressSetCoderPropertiesOpt, 0x1F) + + +#define Z7_IFACEM_ICompressSetCoderProperties(x) \ + x(SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)) +Z7_IFACE_CONSTR_CODER(ICompressSetCoderProperties, 0x20) /* -CODER_INTERFACE(ICompressSetCoderProperties, 0x21) -{ - STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream) PURE; -}; +#define Z7_IFACEM_ICompressSetDecoderProperties(x) \ + x(SetDecoderProperties(ISequentialInStream *inStream)) +Z7_IFACE_CONSTR_CODER(ICompressSetDecoderProperties, 0x21) */ -CODER_INTERFACE(ICompressSetDecoderProperties2, 0x22) -{ +#define Z7_IFACEM_ICompressSetDecoderProperties2(x) \ + x(SetDecoderProperties2(const Byte *data, UInt32 size)) +Z7_IFACE_CONSTR_CODER(ICompressSetDecoderProperties2, 0x22) /* returns: S_OK E_NOTIMP : unsupported properties E_INVALIDARG : incorrect (or unsupported) properties E_OUTOFMEMORY : memory allocation error */ - STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size) PURE; -}; -CODER_INTERFACE(ICompressWriteCoderProperties, 0x23) -{ - STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream) PURE; -}; -CODER_INTERFACE(ICompressGetInStreamProcessedSize, 0x24) -{ - STDMETHOD(GetInStreamProcessedSize)(UInt64 *value) PURE; -}; +#define Z7_IFACEM_ICompressWriteCoderProperties(x) \ + x(WriteCoderProperties(ISequentialOutStream *outStream)) +Z7_IFACE_CONSTR_CODER(ICompressWriteCoderProperties, 0x23) -CODER_INTERFACE(ICompressSetCoderMt, 0x25) -{ - STDMETHOD(SetNumberOfThreads)(UInt32 numThreads) PURE; -}; +#define Z7_IFACEM_ICompressGetInStreamProcessedSize(x) \ + x(GetInStreamProcessedSize(UInt64 *value)) +Z7_IFACE_CONSTR_CODER(ICompressGetInStreamProcessedSize, 0x24) -CODER_INTERFACE(ICompressSetFinishMode, 0x26) -{ - STDMETHOD(SetFinishMode)(UInt32 finishMode) PURE; +#define Z7_IFACEM_ICompressSetCoderMt(x) \ + x(SetNumberOfThreads(UInt32 numThreads)) +Z7_IFACE_CONSTR_CODER(ICompressSetCoderMt, 0x25) +#define Z7_IFACEM_ICompressSetFinishMode(x) \ + x(SetFinishMode(UInt32 finishMode)) +Z7_IFACE_CONSTR_CODER(ICompressSetFinishMode, 0x26) /* finishMode: 0 : partial decoding is allowed. It's default mode for ICompressCoder::Code(), if (outSize) is defined. 1 : full decoding. The stream must be finished at the end of decoding. */ -}; +#define Z7_IFACEM_ICompressGetInStreamProcessedSize2(x) \ + x(GetInStreamProcessedSize2(UInt32 streamIndex, UInt64 *value)) +Z7_IFACE_CONSTR_CODER(ICompressGetInStreamProcessedSize2, 0x27) + +#define Z7_IFACEM_ICompressSetMemLimit(x) \ + x(SetMemLimit(UInt64 memUsage)) +Z7_IFACE_CONSTR_CODER(ICompressSetMemLimit, 0x28) -CODER_INTERFACE(ICompressGetSubStreamSize, 0x30) -{ - STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value) PURE; +/* + ICompressReadUnusedFromInBuf is supported by ICoder object + call ReadUnusedFromInBuf() after ICoder::Code(inStream, ...). + ICoder::Code(inStream, ...) decodes data, and the ICoder object is allowed + to read from inStream to internal buffers more data than minimal data required for decoding. + So we can call ReadUnusedFromInBuf() from same ICoder object to read unused input + data from the internal buffer. + in ReadUnusedFromInBuf(): the Coder is not allowed to use (ISequentialInStream *inStream) object, that was sent to ICoder::Code(). +*/ +#define Z7_IFACEM_ICompressReadUnusedFromInBuf(x) \ + x(ReadUnusedFromInBuf(void *data, UInt32 size, UInt32 *processedSize)) +Z7_IFACE_CONSTR_CODER(ICompressReadUnusedFromInBuf, 0x29) + + +#define Z7_IFACEM_ICompressGetSubStreamSize(x) \ + x(GetSubStreamSize(UInt64 subStream, UInt64 *value)) +Z7_IFACE_CONSTR_CODER(ICompressGetSubStreamSize, 0x30) /* returns: S_OK : (*value) contains the size or estimated size (can be incorrect size) S_FALSE : size is undefined E_NOTIMP : the feature is not implemented - Let's (read_size) is size of data that was already read by ISequentialInStream::Read(). The caller should call GetSubStreamSize() after each Read() and check sizes: if (start_of_subStream + *value < read_size) @@ -189,135 +250,153 @@ CODER_INTERFACE(ICompressGetSubStreamSize, 0x30) subStream++; } */ -}; -CODER_INTERFACE(ICompressSetInStream, 0x31) -{ - STDMETHOD(SetInStream)(ISequentialInStream *inStream) PURE; - STDMETHOD(ReleaseInStream)() PURE; -}; +#define Z7_IFACEM_ICompressSetInStream(x) \ + x(SetInStream(ISequentialInStream *inStream)) \ + x(ReleaseInStream()) +Z7_IFACE_CONSTR_CODER(ICompressSetInStream, 0x31) -CODER_INTERFACE(ICompressSetOutStream, 0x32) -{ - STDMETHOD(SetOutStream)(ISequentialOutStream *outStream) PURE; - STDMETHOD(ReleaseOutStream)() PURE; -}; +#define Z7_IFACEM_ICompressSetOutStream(x) \ + x(SetOutStream(ISequentialOutStream *outStream)) \ + x(ReleaseOutStream()) +Z7_IFACE_CONSTR_CODER(ICompressSetOutStream, 0x32) /* -CODER_INTERFACE(ICompressSetInStreamSize, 0x33) -{ - STDMETHOD(SetInStreamSize)(const UInt64 *inSize) PURE; -}; +#define Z7_IFACEM_ICompressSetInStreamSize(x) \ + x(SetInStreamSize(const UInt64 *inSize)) \ +Z7_IFACE_CONSTR_CODER(ICompressSetInStreamSize, 0x33) */ -CODER_INTERFACE(ICompressSetOutStreamSize, 0x34) -{ - STDMETHOD(SetOutStreamSize)(const UInt64 *outSize) PURE; - +#define Z7_IFACEM_ICompressSetOutStreamSize(x) \ + x(SetOutStreamSize(const UInt64 *outSize)) +Z7_IFACE_CONSTR_CODER(ICompressSetOutStreamSize, 0x34) /* That function initializes decoder structures. Call this function only for stream version of decoder. if (outSize == NULL), then output size is unknown if (outSize != NULL), then the decoder must stop decoding after (*outSize) bytes. */ -}; - -CODER_INTERFACE(ICompressSetBufSize, 0x35) -{ - STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size) PURE; - STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size) PURE; -}; -CODER_INTERFACE(ICompressInitEncoder, 0x36) -{ - STDMETHOD(InitEncoder)() PURE; +#define Z7_IFACEM_ICompressSetBufSize(x) \ + x(SetInBufSize(UInt32 streamIndex, UInt32 size)) \ + x(SetOutBufSize(UInt32 streamIndex, UInt32 size)) + +Z7_IFACE_CONSTR_CODER(ICompressSetBufSize, 0x35) +#define Z7_IFACEM_ICompressInitEncoder(x) \ + x(InitEncoder()) +Z7_IFACE_CONSTR_CODER(ICompressInitEncoder, 0x36) /* That function initializes encoder structures. Call this function only for stream version of encoder. */ -}; -CODER_INTERFACE(ICompressSetInStream2, 0x37) -{ - STDMETHOD(SetInStream2)(UInt32 streamIndex, ISequentialInStream *inStream) PURE; - STDMETHOD(ReleaseInStream2)(UInt32 streamIndex) PURE; -}; +#define Z7_IFACEM_ICompressSetInStream2(x) \ + x(SetInStream2(UInt32 streamIndex, ISequentialInStream *inStream)) \ + x(ReleaseInStream2(UInt32 streamIndex)) +Z7_IFACE_CONSTR_CODER(ICompressSetInStream2, 0x37) /* -CODER_INTERFACE(ICompressSetOutStream2, 0x38) -{ - STDMETHOD(SetOutStream2)(UInt32 streamIndex, ISequentialOutStream *outStream) PURE; - STDMETHOD(ReleaseOutStream2)(UInt32 streamIndex) PURE; -}; - -CODER_INTERFACE(ICompressSetInStreamSize2, 0x39) -{ - STDMETHOD(SetInStreamSize2)(UInt32 streamIndex, const UInt64 *inSize) PURE; -}; +#define Z7_IFACEM_ICompressSetOutStream2(x) \ + x(SetOutStream2(UInt32 streamIndex, ISequentialOutStream *outStream)) + x(ReleaseOutStream2(UInt32 streamIndex)) +Z7_IFACE_CONSTR_CODER(ICompressSetOutStream2, 0x38) + +#define Z7_IFACEM_ICompressSetInStreamSize2(x) \ + x(SetInStreamSize2(UInt32 streamIndex, const UInt64 *inSize)) +Z7_IFACE_CONSTR_CODER(ICompressSetInStreamSize2, 0x39) */ +/* +#define Z7_IFACEM_ICompressInSubStreams(x) \ + x(GetNextInSubStream(UInt64 *streamIndexRes, ISequentialInStream **stream)) +Z7_IFACE_CONSTR_CODER(ICompressInSubStreams, 0x3A) + +#define Z7_IFACEM_ICompressOutSubStreams(x) \ + x(GetNextOutSubStream(UInt64 *streamIndexRes, ISequentialOutStream **stream)) +Z7_IFACE_CONSTR_CODER(ICompressOutSubStreams, 0x3B) +*/ /* ICompressFilter - Filter() converts as most as possible bytes - returns: (outSize): + Filter(Byte *data, UInt32 size) + (size) + converts as most as possible bytes required for fast processing. + Some filters have (smallest_fast_block). + For example, (smallest_fast_block == 16) for AES CBC/CTR filters. + If data stream is not finished, caller must call Filter() for larger block: + where (size >= smallest_fast_block). + if (size >= smallest_fast_block) + { + The filter can leave some bytes at the end of data without conversion: + if there are data alignment reasons or speed reasons. + The caller can read additional data from stream and call Filter() again. + } + If data stream was finished, caller can call Filter() for (size < smallest_fast_block) + + (data) parameter: + Some filters require alignment for any Filter() call: + 1) (stream_offset % alignment_size) == (data % alignment_size) + 2) (alignment_size == 2^N) + where (stream_offset) - is the number of bytes that were already filtered before. + The callers of Filter() are required to meet these requirements. + (alignment_size) can be different: + 16 : for AES filters + 4 or 2 : for some branch convert filters + 1 : for another filters + (alignment_size >= 16) is enough for all current filters of 7-Zip. + But the caller can use larger (alignment_size). + Recommended alignment for (data) of Filter() call is (alignment_size == 64). + Also it's recommended to use aligned value for (size): + (size % alignment_size == 0), + if it's not last call of Filter() for current stream. + + returns: (outSize): + if (outSize == 0) : Filter have not converted anything. + So the caller can stop processing, if data stream was finished. if (outSize <= size) : Filter have converted outSize bytes if (outSize > size) : Filter have not converted anything. and it needs at least outSize bytes to convert one block (it's for crypto block algorithms). */ -#define INTERFACE_ICompressFilter(x) \ - STDMETHOD(Init)() x; \ - STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size) x; \ +#define Z7_IFACEM_ICompressFilter(x) \ + x(Init()) \ + x##2(UInt32, Filter(Byte *data, UInt32 size)) +Z7_IFACE_CONSTR_CODER(ICompressFilter, 0x40) -CODER_INTERFACE(ICompressFilter, 0x40) -{ - INTERFACE_ICompressFilter(PURE); -}; +#define Z7_IFACEM_ICompressCodecsInfo(x) \ + x(GetNumMethods(UInt32 *numMethods)) \ + x(GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) \ + x(CreateDecoder(UInt32 index, const GUID *iid, void* *coder)) \ + x(CreateEncoder(UInt32 index, const GUID *iid, void* *coder)) +Z7_IFACE_CONSTR_CODER(ICompressCodecsInfo, 0x60) -CODER_INTERFACE(ICompressCodecsInfo, 0x60) -{ - STDMETHOD(GetNumMethods)(UInt32 *numMethods) PURE; - STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) PURE; - STDMETHOD(CreateDecoder)(UInt32 index, const GUID *iid, void **coder) PURE; - STDMETHOD(CreateEncoder)(UInt32 index, const GUID *iid, void **coder) PURE; -}; +#define Z7_IFACEM_ISetCompressCodecsInfo(x) \ + x(SetCompressCodecsInfo(ICompressCodecsInfo *compressCodecsInfo)) +Z7_IFACE_CONSTR_CODER(ISetCompressCodecsInfo, 0x61) -CODER_INTERFACE(ISetCompressCodecsInfo, 0x61) -{ - STDMETHOD(SetCompressCodecsInfo)(ICompressCodecsInfo *compressCodecsInfo) PURE; -}; - -CODER_INTERFACE(ICryptoProperties, 0x80) -{ - STDMETHOD(SetKey)(const Byte *data, UInt32 size) PURE; - STDMETHOD(SetInitVector)(const Byte *data, UInt32 size) PURE; -}; +#define Z7_IFACEM_ICryptoProperties(x) \ + x(SetKey(const Byte *data, UInt32 size)) \ + x(SetInitVector(const Byte *data, UInt32 size)) +Z7_IFACE_CONSTR_CODER(ICryptoProperties, 0x80) /* -CODER_INTERFACE(ICryptoResetSalt, 0x88) -{ - STDMETHOD(ResetSalt)() PURE; -}; + x(ResetSalt()) +Z7_IFACE_CONSTR_CODER(ICryptoResetSalt, 0x88) */ -CODER_INTERFACE(ICryptoResetInitVector, 0x8C) -{ - STDMETHOD(ResetInitVector)() PURE; - +#define Z7_IFACEM_ICryptoResetInitVector(x) \ + x(ResetInitVector()) +Z7_IFACE_CONSTR_CODER(ICryptoResetInitVector, 0x8C) /* Call ResetInitVector() only for encoding. Call ResetInitVector() before encoding and before WriteCoderProperties(). Crypto encoder can create random IV in that function. */ -}; -CODER_INTERFACE(ICryptoSetPassword, 0x90) -{ - STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size) PURE; -}; +#define Z7_IFACEM_ICryptoSetPassword(x) \ + x(CryptoSetPassword(const Byte *data, UInt32 size)) +Z7_IFACE_CONSTR_CODER(ICryptoSetPassword, 0x90) -CODER_INTERFACE(ICryptoSetCRC, 0xA0) -{ - STDMETHOD(CryptoSetCRC)(UInt32 crc) PURE; -}; +#define Z7_IFACEM_ICryptoSetCRC(x) \ + x(CryptoSetCRC(UInt32 crc)) +Z7_IFACE_CONSTR_CODER(ICryptoSetCRC, 0xA0) namespace NMethodPropID @@ -333,28 +412,53 @@ namespace NMethodPropID kDescription, kDecoderIsAssigned, kEncoderIsAssigned, - kDigestSize + kDigestSize, + kIsFilter }; } - -#define INTERFACE_IHasher(x) \ - STDMETHOD_(void, Init)() throw() x; \ - STDMETHOD_(void, Update)(const void *data, UInt32 size) throw() x; \ - STDMETHOD_(void, Final)(Byte *digest) throw() x; \ - STDMETHOD_(UInt32, GetDigestSize)() throw() x; \ - -CODER_INTERFACE(IHasher, 0xC0) +namespace NModuleInterfaceType { - INTERFACE_IHasher(PURE) -}; + /* + virtual destructor in IUnknown: + - no : 7-Zip (Windows) + - no : 7-Zip (Linux) (v23) in default mode + - yes : p7zip + - yes : 7-Zip (Linux) before v23 + - yes : 7-Zip (Linux) (v23), if Z7_USE_VIRTUAL_DESTRUCTOR_IN_IUNKNOWN is defined + */ + const UInt32 k_IUnknown_VirtDestructor_No = 0; + const UInt32 k_IUnknown_VirtDestructor_Yes = 1; + const UInt32 k_IUnknown_VirtDestructor_ThisModule = + #if !defined(_WIN32) && defined(Z7_USE_VIRTUAL_DESTRUCTOR_IN_IUNKNOWN) + k_IUnknown_VirtDestructor_Yes; + #else + k_IUnknown_VirtDestructor_No; + #endif +} -CODER_INTERFACE(IHashers, 0xC1) +namespace NModulePropID { - STDMETHOD_(UInt32, GetNumHashers)() PURE; - STDMETHOD(GetHasherProp)(UInt32 index, PROPID propID, PROPVARIANT *value) PURE; - STDMETHOD(CreateHasher)(UInt32 index, IHasher **hasher) PURE; -}; + enum EEnum + { + kInterfaceType, // VT_UI4 + kVersion // VT_UI4 + }; +} + + +#define Z7_IFACEM_IHasher(x) \ + x##2(void, Init()) \ + x##2(void, Update(const void *data, UInt32 size)) \ + x##2(void, Final(Byte *digest)) \ + x##2(UInt32, GetDigestSize()) +Z7_IFACE_CONSTR_CODER(IHasher, 0xC0) + +#define Z7_IFACEM_IHashers(x) \ + x##2(UInt32, GetNumHashers()) \ + x(GetHasherProp(UInt32 index, PROPID propID, PROPVARIANT *value)) \ + x(CreateHasher(UInt32 index, IHasher **hasher)) +Z7_IFACE_CONSTR_CODER(IHashers, 0xC1) extern "C" { @@ -366,6 +470,8 @@ extern "C" typedef HRESULT (WINAPI *Func_GetHashers)(IHashers **hashers); typedef HRESULT (WINAPI *Func_SetCodecs)(ICompressCodecsInfo *compressCodecsInfo); + typedef HRESULT (WINAPI *Func_GetModuleProp)(PROPID propID, PROPVARIANT *value); } +Z7_PURE_INTERFACES_END #endif diff --git a/3rdparty/lzma/CPP/7zip/IDecl.h b/3rdparty/lzma/CPP/7zip/IDecl.h index 077ef0ee3f5..c4d454127fc 100644 --- a/3rdparty/lzma/CPP/7zip/IDecl.h +++ b/3rdparty/lzma/CPP/7zip/IDecl.h @@ -1,8 +1,9 @@ // IDecl.h -#ifndef __IDECL_H -#define __IDECL_H +#ifndef ZIP7_INC_IDECL_H +#define ZIP7_INC_IDECL_H +#include "../Common/Common.h" #include "../Common/MyUnknown.h" #define k_7zip_GUID_Data1 0x23170F69 @@ -14,15 +15,62 @@ #define k_7zip_GUID_Data3_Encoder 0x2791 #define k_7zip_GUID_Data3_Hasher 0x2792 - -#define DECL_INTERFACE_SUB(i, base, groupId, subId) \ - DEFINE_GUID(IID_ ## i, \ +#define Z7_DECL_IFACE_7ZIP_SUB(i, _base, groupId, subId) \ + Z7_DEFINE_GUID(IID_ ## i, \ k_7zip_GUID_Data1, \ k_7zip_GUID_Data2, \ k_7zip_GUID_Data3_Common, \ 0, 0, 0, (groupId), 0, (subId), 0, 0); \ - struct i: public base + struct Z7_DECLSPEC_NOVTABLE i: public _base + +#define Z7_DECL_IFACE_7ZIP(i, groupId, subId) \ + Z7_DECL_IFACE_7ZIP_SUB(i, IUnknown, groupId, subId) + + +#ifdef COM_DECLSPEC_NOTHROW +#define Z7_COMWF_B COM_DECLSPEC_NOTHROW STDMETHODIMP +#define Z7_COMWF_B_(t) COM_DECLSPEC_NOTHROW STDMETHODIMP_(t) +#else +#define Z7_COMWF_B STDMETHODIMP +#define Z7_COMWF_B_(t) STDMETHODIMP_(t) +#endif + +#if defined(_MSC_VER) && !defined(COM_DECLSPEC_NOTHROW) +#define Z7_COM7F_B __declspec(nothrow) STDMETHODIMP +#define Z7_COM7F_B_(t) __declspec(nothrow) STDMETHODIMP_(t) +#else +#define Z7_COM7F_B Z7_COMWF_B +#define Z7_COM7F_B_(t) Z7_COMWF_B_(t) +#endif + +// #define Z7_COM7F_E Z7_noexcept +#define Z7_COM7F_E throw() +#define Z7_COM7F_EO Z7_COM7F_E Z7_override +#define Z7_COM7F_EOF Z7_COM7F_EO Z7_final +#define Z7_COM7F_IMF(f) Z7_COM7F_B f Z7_COM7F_E +#define Z7_COM7F_IMF2(t, f) Z7_COM7F_B_(t) f Z7_COM7F_E + +#define Z7_COM7F_PURE(f) virtual Z7_COM7F_IMF(f) =0; +#define Z7_COM7F_PURE2(t, f) virtual Z7_COM7F_IMF2(t, f) =0; +#define Z7_COM7F_IMP(f) Z7_COM7F_IMF(f) Z7_override Z7_final; +#define Z7_COM7F_IMP2(t, f) Z7_COM7F_IMF2(t, f) Z7_override Z7_final; +#define Z7_COM7F_IMP_NONFINAL(f) Z7_COM7F_IMF(f) Z7_override; +#define Z7_COM7F_IMP_NONFINAL2(t, f) Z7_COM7F_IMF2(t, f) Z7_override; + +#define Z7_IFACE_PURE(name) Z7_IFACEN_ ## name(=0;) +#define Z7_IFACE_IMP(name) Z7_IFACEN_ ## name(Z7_override Z7_final;) + +#define Z7_IFACE_COM7_PURE(name) Z7_IFACEM_ ## name(Z7_COM7F_PURE) +#define Z7_IFACE_COM7_IMP(name) Z7_IFACEM_ ## name(Z7_COM7F_IMP) +#define Z7_IFACE_COM7_IMP_NONFINAL(name) Z7_IFACEM_ ## name(Z7_COM7F_IMP_NONFINAL) + + +#define Z7_IFACE_DECL_PURE(name) \ + DECLARE_INTERFACE(name) \ + { Z7_IFACE_PURE(name) }; -#define DECL_INTERFACE(i, groupId, subId) DECL_INTERFACE_SUB(i, IUnknown, groupId, subId) +#define Z7_IFACE_DECL_PURE_(name, baseiface) \ + DECLARE_INTERFACE_(name, baseiface) \ + { Z7_IFACE_PURE(name) }; #endif diff --git a/3rdparty/lzma/CPP/7zip/IPassword.h b/3rdparty/lzma/CPP/7zip/IPassword.h index 7ea45537e65..689f08cb4b4 100644 --- a/3rdparty/lzma/CPP/7zip/IPassword.h +++ b/3rdparty/lzma/CPP/7zip/IPassword.h @@ -1,23 +1,54 @@ // IPassword.h -#ifndef __IPASSWORD_H -#define __IPASSWORD_H +#ifndef ZIP7_INC_IPASSWORD_H +#define ZIP7_INC_IPASSWORD_H #include "../Common/MyTypes.h" -#include "../Common/MyUnknown.h" #include "IDecl.h" -#define PASSWORD_INTERFACE(i, x) DECL_INTERFACE(i, 5, x) +Z7_PURE_INTERFACES_BEGIN -PASSWORD_INTERFACE(ICryptoGetTextPassword, 0x10) -{ - STDMETHOD(CryptoGetTextPassword)(BSTR *password) PURE; -}; +#define Z7_IFACE_CONSTR_PASSWORD(i, n) \ + Z7_DECL_IFACE_7ZIP(i, 5, n) \ + { Z7_IFACE_COM7_PURE(i) }; -PASSWORD_INTERFACE(ICryptoGetTextPassword2, 0x11) -{ - STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password) PURE; -}; +/* +How to use output parameter (BSTR *password): +in: The caller is required to set BSTR value as NULL (no string). + The callee (in 7-Zip code) ignores the input value stored in BSTR variable, + +out: The callee rewrites BSTR variable (*password) with new allocated string pointer. + The caller must free BSTR string with function SysFreeString(); +*/ + +#define Z7_IFACEM_ICryptoGetTextPassword(x) \ + x(CryptoGetTextPassword(BSTR *password)) +Z7_IFACE_CONSTR_PASSWORD(ICryptoGetTextPassword, 0x10) + + +/* +CryptoGetTextPassword2() +in: + The caller is required to set BSTR value as NULL (no string). + The caller is not required to set (*passwordIsDefined) value. + +out: + Return code: != S_OK : error code + Return code: S_OK : success + + if (*passwordIsDefined == 1), the variable (*password) contains password string + + if (*passwordIsDefined == 0), the password is not defined, + but the callee still could set (*password) to some allocated string, for example, as empty string. + + The caller must free BSTR string with function SysFreeString() +*/ + +#define Z7_IFACEM_ICryptoGetTextPassword2(x) \ + x(CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)) +Z7_IFACE_CONSTR_PASSWORD(ICryptoGetTextPassword2, 0x11) + +Z7_PURE_INTERFACES_END #endif diff --git a/3rdparty/lzma/CPP/7zip/IProgress.h b/3rdparty/lzma/CPP/7zip/IProgress.h index fac951eca48..67149830bd7 100644 --- a/3rdparty/lzma/CPP/7zip/IProgress.h +++ b/3rdparty/lzma/CPP/7zip/IProgress.h @@ -1,19 +1,20 @@ // IProgress.h -#ifndef __IPROGRESS_H -#define __IPROGRESS_H +#ifndef ZIP7_INC_IPROGRESS_H +#define ZIP7_INC_IPROGRESS_H #include "../Common/MyTypes.h" #include "IDecl.h" -#define INTERFACE_IProgress(x) \ - STDMETHOD(SetTotal)(UInt64 total) x; \ - STDMETHOD(SetCompleted)(const UInt64 *completeValue) x; \ +Z7_PURE_INTERFACES_BEGIN -DECL_INTERFACE(IProgress, 0, 5) -{ - INTERFACE_IProgress(PURE) -}; +#define Z7_IFACEM_IProgress(x) \ + x(SetTotal(UInt64 total)) \ + x(SetCompleted(const UInt64 *completeValue)) \ +Z7_DECL_IFACE_7ZIP(IProgress, 0, 5) + { Z7_IFACE_COM7_PURE(IProgress) }; + +Z7_PURE_INTERFACES_END #endif diff --git a/3rdparty/lzma/CPP/7zip/IStream.h b/3rdparty/lzma/CPP/7zip/IStream.h index 9a0bcbf3d72..4a58bc973ac 100644 --- a/3rdparty/lzma/CPP/7zip/IStream.h +++ b/3rdparty/lzma/CPP/7zip/IStream.h @@ -1,24 +1,28 @@ // IStream.h -#ifndef __ISTREAM_H -#define __ISTREAM_H +#ifndef ZIP7_INC_ISTREAM_H +#define ZIP7_INC_ISTREAM_H #include "../Common/MyTypes.h" #include "../Common/MyWindows.h" #include "IDecl.h" -#define STREAM_INTERFACE_SUB(i, base, x) DECL_INTERFACE_SUB(i, base, 3, x) -#define STREAM_INTERFACE(i, x) STREAM_INTERFACE_SUB(i, IUnknown, x) +Z7_PURE_INTERFACES_BEGIN -STREAM_INTERFACE(ISequentialInStream, 0x01) -{ - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) PURE; - - /* +#define Z7_IFACE_CONSTR_STREAM_SUB(i, base, n) \ + Z7_DECL_IFACE_7ZIP_SUB(i, base, 3, n) \ + { Z7_IFACE_COM7_PURE(i) }; + +#define Z7_IFACE_CONSTR_STREAM(i, n) \ + Z7_IFACE_CONSTR_STREAM_SUB(i, IUnknown, n) + + +/* +ISequentialInStream::Read() The requirement for caller: (processedSize != NULL). The callee can allow (processedSize == NULL) for compatibility reasons. - + if (size == 0), this function returns S_OK and (*processedSize) is set to 0. if (size != 0) @@ -31,21 +35,21 @@ STREAM_INTERFACE(ISequentialInStream, 0x01) If seek pointer before Read() call was changed to position past the end of stream: if (seek_pointer >= stream_size), this function returns S_OK and (*processedSize) is set to 0. - + ERROR CASES: If the function returns error code, then (*processedSize) is size of data written to (data) buffer (it can be data before error or data with errors). The recommended way for callee to work with reading errors: 1) write part of data before error to (data) buffer and return S_OK. 2) return error code for further calls of Read(). - */ -}; +*/ +#define Z7_IFACEM_ISequentialInStream(x) \ + x(Read(void *data, UInt32 size, UInt32 *processedSize)) +Z7_IFACE_CONSTR_STREAM(ISequentialInStream, 0x01) -STREAM_INTERFACE(ISequentialOutStream, 0x02) -{ - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) PURE; - - /* + +/* +ISequentialOutStream::Write() The requirement for caller: (processedSize != NULL). The callee can allow (processedSize == NULL) for compatibility reasons. @@ -59,8 +63,13 @@ STREAM_INTERFACE(ISequentialOutStream, 0x02) ERROR CASES: If the function returns error code, then (*processedSize) is size of data written from (data) buffer. - */ -}; +*/ +#define Z7_IFACEM_ISequentialOutStream(x) \ + x(Write(const void *data, UInt32 size, UInt32 *processedSize)) +Z7_IFACE_CONSTR_STREAM(ISequentialOutStream, 0x02) + + +#ifdef _WIN32 #ifdef __HRESULT_FROM_WIN32 #define HRESULT_WIN32_ERROR_NEGATIVE_SEEK __HRESULT_FROM_WIN32(ERROR_NEGATIVE_SEEK) @@ -68,43 +77,44 @@ STREAM_INTERFACE(ISequentialOutStream, 0x02) #define HRESULT_WIN32_ERROR_NEGATIVE_SEEK HRESULT_FROM_WIN32(ERROR_NEGATIVE_SEEK) #endif -/* Seek() Function - If you seek before the beginning of the stream, Seek() function returns error code: +#else + +#define HRESULT_WIN32_ERROR_NEGATIVE_SEEK MY_E_ERROR_NEGATIVE_SEEK + +#endif + + +/* +IInStream::Seek() / IOutStream::Seek() + If you seek to position before the beginning of the stream, + Seek() function returns error code: Recommended error code is __HRESULT_FROM_WIN32(ERROR_NEGATIVE_SEEK). or STG_E_INVALIDFUNCTION - It is allowed to seek past the end of the stream. - - if Seek() returns error, then the value of *newPosition is undefined. */ -STREAM_INTERFACE_SUB(IInStream, ISequentialInStream, 0x03) -{ - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE; -}; +#define Z7_IFACEM_IInStream(x) \ + x(Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) +Z7_IFACE_CONSTR_STREAM_SUB(IInStream, ISequentialInStream, 0x03) -STREAM_INTERFACE_SUB(IOutStream, ISequentialOutStream, 0x04) -{ - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE; - STDMETHOD(SetSize)(UInt64 newSize) PURE; -}; +#define Z7_IFACEM_IOutStream(x) \ + x(Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) \ + x(SetSize(UInt64 newSize)) +Z7_IFACE_CONSTR_STREAM_SUB(IOutStream, ISequentialOutStream, 0x04) -STREAM_INTERFACE(IStreamGetSize, 0x06) -{ - STDMETHOD(GetSize)(UInt64 *size) PURE; -}; +#define Z7_IFACEM_IStreamGetSize(x) \ + x(GetSize(UInt64 *size)) +Z7_IFACE_CONSTR_STREAM(IStreamGetSize, 0x06) -STREAM_INTERFACE(IOutStreamFinish, 0x07) -{ - STDMETHOD(OutStreamFinish)() PURE; -}; +#define Z7_IFACEM_IOutStreamFinish(x) \ + x(OutStreamFinish()) +Z7_IFACE_CONSTR_STREAM(IOutStreamFinish, 0x07) +#define Z7_IFACEM_IStreamGetProps(x) \ + x(GetProps(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib)) +Z7_IFACE_CONSTR_STREAM(IStreamGetProps, 0x08) -STREAM_INTERFACE(IStreamGetProps, 0x08) -{ - STDMETHOD(GetProps)(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib) PURE; -}; struct CStreamFileProps { @@ -119,9 +129,79 @@ struct CStreamFileProps FILETIME MTime; }; -STREAM_INTERFACE(IStreamGetProps2, 0x09) -{ - STDMETHOD(GetProps2)(CStreamFileProps *props) PURE; -}; +#define Z7_IFACEM_IStreamGetProps2(x) \ + x(GetProps2(CStreamFileProps *props)) +Z7_IFACE_CONSTR_STREAM(IStreamGetProps2, 0x09) + +#define Z7_IFACEM_IStreamGetProp(x) \ + x(GetProperty(PROPID propID, PROPVARIANT *value)) \ + x(ReloadProps()) +Z7_IFACE_CONSTR_STREAM(IStreamGetProp, 0x0a) + + +/* +IStreamSetRestriction::SetRestriction(UInt64 begin, UInt64 end) + + It sets region of data in output stream that is restricted. + For restricted region it's expected (or allowed) + to change data with different calls of Write()/SetSize(). + Another regions of output stream will be supposed as non-restricted: + - The callee usually doesn't flush the data in restricted region. + - The callee usually can flush data from non-restricted region. + +inputs: + + (begin > end) is not allowed, and returns E_FAIL; + + if (begin == end) + { + it means that there is no region restriction for flushing. + The callee is allowed to flush already written data and + is allowed to flush all data in future calls of + ISequentialOutStream::Write(), but before next call of SetRestriction(). + The pair of values (begin == 0 && end == 0) is recommended to + remove all restrictions. + } + + if (begin < end) + { + it means that callee must NOT to flush any data in region [begin, end). + The caller is allowed to Seek() to that region and rewrite the + data in that restriction region. + if (end == (UInt64(Int64)-1) + { + there is no upper bound for restricted region. + So non-restricted region will be [0, begin) in that case + } + + Note: it's not expected that some already written region was marked as + non-restricted by old call SetRestriction() and later the part of + that region was marked as restricted with new call SetRestriction(). + For example, for different calls with non-empty restricted regions: + (begin_new >= begin_old) is expected : + { + SetRestriction(begin_old, ...) + ... + SetRestriction(begin_new, ...) + } + } + + returns: + - if (begin > end) it return ERROR code (E_FAIL) + - S_OK : if no errors. + - Also the call of SetRestriction() can initiate the flushing of already written data. + So it can return the result of that flushing. + + Note: IOutStream::SetSize() also can change the data. + So it's not expected the call + IOutStream::SetSize() to unrestricted already written region. +*/ + +#define Z7_IFACEM_IStreamSetRestriction(x) \ + x(SetRestriction(UInt64 begin, UInt64 end)) \ + +Z7_IFACE_CONSTR_STREAM(IStreamSetRestriction, 0x10) + +Z7_PURE_INTERFACES_END #endif diff --git a/3rdparty/lzma/CPP/7zip/LzFindOpt.mak b/3rdparty/lzma/CPP/7zip/LzFindOpt.mak new file mode 100644 index 00000000000..169e10f0b1e --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/LzFindOpt.mak @@ -0,0 +1,7 @@ +!IF defined(USE_C_LZFINDOPT) || "$(PLATFORM)" != "x64" +C_OBJS = $(C_OBJS) \ + $O\LzFindOpt.obj +!ELSE +ASM_OBJS = $(ASM_OBJS) \ + $O\LzFindOpt.obj +!ENDIF diff --git a/3rdparty/lzma/CPP/7zip/LzmaDec.mak b/3rdparty/lzma/CPP/7zip/LzmaDec.mak new file mode 100644 index 00000000000..3beb5052ee5 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/LzmaDec.mak @@ -0,0 +1,7 @@ +!IF "$(PLATFORM)" == "x64" +!IFNDEF NO_ASM +CFLAGS_C_SPEC = -DZ7_LZMA_DEC_OPT +ASM_OBJS = $(ASM_OBJS) \ + $O\LzmaDecOpt.obj +!ENDIF +!ENDIF diff --git a/3rdparty/lzma/CPP/7zip/LzmaDec_gcc.mak b/3rdparty/lzma/CPP/7zip/LzmaDec_gcc.mak new file mode 100644 index 00000000000..51924f50565 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/LzmaDec_gcc.mak @@ -0,0 +1,14 @@ +ifdef USE_ASM +ifdef IS_X64 +USE_LZMA_DEC_ASM=1 +endif +ifdef IS_ARM64 +USE_LZMA_DEC_ASM=1 +endif +endif + +ifdef USE_LZMA_DEC_ASM + +LZMA_DEC_OPT_OBJS= $O/LzmaDecOpt.o + +endif diff --git a/3rdparty/lzma/CPP/7zip/MyVersionInfo.rc b/3rdparty/lzma/CPP/7zip/MyVersionInfo.rc index fab66860a5d..fc63d798a9f 100644 --- a/3rdparty/lzma/CPP/7zip/MyVersionInfo.rc +++ b/3rdparty/lzma/CPP/7zip/MyVersionInfo.rc @@ -1,2 +1,2 @@ #include "MyVersion.h" -#include "..\..\C\7zVersion.rc" +#include "../../C/7zVersion.rc" diff --git a/3rdparty/lzma/CPP/7zip/PropID.h b/3rdparty/lzma/CPP/7zip/PropID.h index 1822f402b9f..e0747942832 100644 --- a/3rdparty/lzma/CPP/7zip/PropID.h +++ b/3rdparty/lzma/CPP/7zip/PropID.h @@ -1,7 +1,7 @@ // PropID.h -#ifndef __7ZIP_PROP_ID_H -#define __7ZIP_PROP_ID_H +#ifndef ZIP7_INC_7ZIP_PROP_ID_H +#define ZIP7_INC_7ZIP_PROP_ID_H #include "../Common/MyTypes.h" @@ -103,6 +103,15 @@ enum kpidReadOnly, kpidOutName, kpidCopyLink, + kpidArcFileName, + kpidIsHash, + kpidChangeTime, + kpidUserId, + kpidGroupId, + kpidDeviceMajor, + kpidDeviceMinor, + kpidDevMajor, + kpidDevMinor, kpid_NUM_DEFINED, @@ -124,4 +133,46 @@ const UInt32 kpv_ErrorFlags_DataError = 1 << 9; const UInt32 kpv_ErrorFlags_CrcError = 1 << 10; // const UInt32 kpv_ErrorFlags_Unsupported = 1 << 11; +/* +linux ctime : + file metadata was last changed. + changing the file modification time + counts as a metadata change, so will also have the side effect of updating the ctime. + +PROPVARIANT for timestamps in 7-Zip: +{ + vt = VT_FILETIME + wReserved1: set precision level + 0 : base value (backward compatibility value) + only filetime is used (7 digits precision). + wReserved2 and wReserved3 can contain random data + 1 : Unix (1 sec) + 2 : DOS (2 sec) + 3 : High Precision (1 ns) + 16 - 3 : (reserved) = 1 day + 16 - 2 : (reserved) = 1 hour + 16 - 1 : (reserved) = 1 minute + 16 + 0 : 1 sec (0 digits after point) + 16 + (1,2,3,4,5,6,7,8,9) : set subsecond precision level : + (number of decimal digits after point) + 16 + 9 : 1 ns (9 digits after point) + wReserved2 = ns % 100 : if (8 or 9 digits pecision) + = 0 : if not (8 or 9 digits pecision) + wReserved3 = 0; + filetime +} + +NOTE: TAR-PAX archives created by GNU TAR don't keep + whole information about original level of precision, + and timestamp are stored in reduced form, where tail zero + digits after point are removed. + So 7-Zip can return different precision levels for different items for such TAR archives. +*/ + +/* +TimePrec returned by IOutArchive::GetFileTimeType() +is used only for updating, when we compare MTime timestamp +from archive with timestamp from directory. +*/ + #endif diff --git a/3rdparty/lzma/CPP/7zip/Sha256.mak b/3rdparty/lzma/CPP/7zip/Sha256.mak new file mode 100644 index 00000000000..0bdbcb60283 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/Sha256.mak @@ -0,0 +1,13 @@ +COMMON_OBJS = $(COMMON_OBJS) \ + $O\Sha256Prepare.obj + +C_OBJS = $(C_OBJS) \ + $O\Sha256.obj + +!IF defined(USE_C_SHA) || "$(PLATFORM)" == "arm" || "$(PLATFORM)" == "arm64" +C_OBJS = $(C_OBJS) \ + $O\Sha256Opt.obj +!ELSEIF "$(PLATFORM)" != "ia64" && "$(PLATFORM)" != "mips" && "$(PLATFORM)" != "arm" && "$(PLATFORM)" != "arm64" +ASM_OBJS = $(ASM_OBJS) \ + $O\Sha256Opt.obj +!ENDIF diff --git a/3rdparty/lzma/CPP/7zip/UI/Client7z/Client7z.cpp b/3rdparty/lzma/CPP/7zip/UI/Client7z/Client7z.cpp index 55650cfa0fe..121a2f1051f 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Client7z/Client7z.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Client7z/Client7z.cpp @@ -5,10 +5,9 @@ #include <stdio.h> #include "../../../Common/MyWindows.h" - -#include "../../../Common/Defs.h" #include "../../../Common/MyInitGuid.h" +#include "../../../Common/Defs.h" #include "../../../Common/IntToString.h" #include "../../../Common/StringConvert.h" @@ -28,42 +27,74 @@ #include "../../../../C/7zVersion.h" #ifdef _WIN32 -HINSTANCE g_hInstance = 0; +extern +HINSTANCE g_hInstance; +HINSTANCE g_hInstance = NULL; #endif -// Tou can find the list of all GUIDs in Guid.txt file. -// use another CLSIDs, if you want to support other formats (zip, rar, ...). -// {23170F69-40C1-278A-1000-000110070000} +// You can find full list of all GUIDs supported by 7-Zip in Guid.txt file. +// 7z format GUID: {23170F69-40C1-278A-1000-000110070000} -DEFINE_GUID(CLSID_CFormat7z, - 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x07, 0x00, 0x00); -DEFINE_GUID(CLSID_CFormatXz, - 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x0C, 0x00, 0x00); +#define DEFINE_GUID_ARC(name, id) Z7_DEFINE_GUID(name, \ + 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, id, 0x00, 0x00); -#define CLSID_Format CLSID_CFormat7z -// #define CLSID_Format CLSID_CFormatXz +enum +{ + kId_Zip = 1, + kId_BZip2 = 2, + kId_7z = 7, + kId_Xz = 0xC, + kId_Tar = 0xEE, + kId_GZip = 0xEF +}; + +// use another id, if you want to support other formats (zip, Xz, ...). +// DEFINE_GUID_ARC (CLSID_Format, kId_Zip) +// DEFINE_GUID_ARC (CLSID_Format, kId_BZip2) +// DEFINE_GUID_ARC (CLSID_Format, kId_Xz) +// DEFINE_GUID_ARC (CLSID_Format, kId_Tar) +// DEFINE_GUID_ARC (CLSID_Format, kId_GZip) +DEFINE_GUID_ARC (CLSID_Format, kId_7z) using namespace NWindows; using namespace NFile; using namespace NDir; +#ifdef _WIN32 #define kDllName "7z.dll" +#else +#define kDllName "7z.so" +#endif -static const char *kCopyrightString = "\n7-Zip " MY_VERSION -" (" kDllName " client) " -MY_COPYRIGHT " " MY_DATE "\n"; +static const char * const kCopyrightString = + "\n" + "7-Zip" + " (" kDllName " client)" + " " MY_VERSION + " : " MY_COPYRIGHT_DATE + "\n"; -static const char *kHelpString = -"Usage: Client7z.exe [a | l | x ] archive.7z [fileName ...]\n" +static const char * const kHelpString = +"Usage: 7zcl.exe [a | l | x] archive.7z [fileName ...]\n" "Examples:\n" -" Client7z.exe a archive.7z f1.txt f2.txt : compress two files to archive.7z\n" -" Client7z.exe l archive.7z : List contents of archive.7z\n" -" Client7z.exe x archive.7z : eXtract files from archive.7z\n"; +" 7zcl.exe a archive.7z f1.txt f2.txt : compress two files to archive.7z\n" +" 7zcl.exe l archive.7z : List contents of archive.7z\n" +" 7zcl.exe x archive.7z : eXtract files from archive.7z\n"; -static AString FStringToConsoleString(const FString &s) +static void Convert_UString_to_AString(const UString &s, AString &temp) { - return GetOemString(fs2us(s)); + int codePage = CP_OEMCP; + /* + int g_CodePage = -1; + int codePage = g_CodePage; + if (codePage == -1) + codePage = CP_OEMCP; + if (codePage == CP_UTF8) + ConvertUnicodeToUTF8(s, temp); + else + */ + UnicodeStringToMultiByte2(temp, s, (UINT)codePage); } static FString CmdStringToFString(const char *s) @@ -71,46 +102,58 @@ static FString CmdStringToFString(const char *s) return us2fs(GetUnicodeString(s)); } -static void PrintString(const UString &s) +static void Print(const char *s) +{ + fputs(s, stdout); +} + +static void Print(const AString &s) +{ + Print(s.Ptr()); +} + +static void Print(const UString &s) { - printf("%s", (LPCSTR)GetOemString(s)); + AString as; + Convert_UString_to_AString(s, as); + Print(as); } -static void PrintString(const AString &s) +static void Print(const wchar_t *s) { - printf("%s", (LPCSTR)s); + Print(UString(s)); } static void PrintNewLine() { - PrintString("\n"); + Print("\n"); } -static void PrintStringLn(const AString &s) +static void PrintStringLn(const char *s) { - PrintString(s); + Print(s); PrintNewLine(); } -static void PrintError(const char *message, const FString &name) +static void PrintError(const char *message) { - printf("Error: %s", (LPCSTR)message); + Print("Error: "); PrintNewLine(); - PrintString(FStringToConsoleString(name)); + Print(message); PrintNewLine(); } -static void PrintError(const AString &s) +static void PrintError(const char *message, const FString &name) { - PrintNewLine(); - PrintString(s); - PrintNewLine(); + PrintError(message); + Print(name); } + static HRESULT IsArchiveItemProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result) { NCOM::CPropVariant prop; - RINOK(archive->GetProperty(index, propID, &prop)); + RINOK(archive->GetProperty(index, propID, &prop)) if (prop.vt == VT_BOOL) result = VARIANT_BOOLToBool(prop.boolVal); else if (prop.vt == VT_EMPTY) @@ -126,25 +169,20 @@ static HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &resu } -static const wchar_t *kEmptyFileAlias = L"[Content]"; +static const wchar_t * const kEmptyFileAlias = L"[Content]"; ////////////////////////////////////////////////////////////// // Archive Open callback class -class CArchiveOpenCallback: +class CArchiveOpenCallback Z7_final: public IArchiveOpenCallback, public ICryptoGetTextPassword, public CMyUnknownImp { + Z7_IFACES_IMP_UNK_2(IArchiveOpenCallback, ICryptoGetTextPassword) public: - MY_UNKNOWN_IMP1(ICryptoGetTextPassword) - - STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes); - STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes); - - STDMETHOD(CryptoGetTextPassword)(BSTR *password); bool PasswordIsDefined; UString Password; @@ -152,17 +190,17 @@ public: CArchiveOpenCallback() : PasswordIsDefined(false) {} }; -STDMETHODIMP CArchiveOpenCallback::SetTotal(const UInt64 * /* files */, const UInt64 * /* bytes */) +Z7_COM7F_IMF(CArchiveOpenCallback::SetTotal(const UInt64 * /* files */, const UInt64 * /* bytes */)) { return S_OK; } -STDMETHODIMP CArchiveOpenCallback::SetCompleted(const UInt64 * /* files */, const UInt64 * /* bytes */) +Z7_COM7F_IMF(CArchiveOpenCallback::SetCompleted(const UInt64 * /* files */, const UInt64 * /* bytes */)) { return S_OK; } -STDMETHODIMP CArchiveOpenCallback::CryptoGetTextPassword(BSTR *password) +Z7_COM7F_IMF(CArchiveOpenCallback::CryptoGetTextPassword(BSTR *password)) { if (!PasswordIsDefined) { @@ -176,43 +214,115 @@ STDMETHODIMP CArchiveOpenCallback::CryptoGetTextPassword(BSTR *password) } + +static const char * const kIncorrectCommand = "incorrect command"; + ////////////////////////////////////////////////////////////// // Archive Extracting callback class -static const char *kTestingString = "Testing "; -static const char *kExtractingString = "Extracting "; -static const char *kSkippingString = "Skipping "; +static const char * const kTestingString = "Testing "; +static const char * const kExtractingString = "Extracting "; +static const char * const kSkippingString = "Skipping "; +static const char * const kReadingString = "Reading "; -static const char *kUnsupportedMethod = "Unsupported Method"; -static const char *kCRCFailed = "CRC Failed"; -static const char *kDataError = "Data Error"; -static const char *kUnavailableData = "Unavailable data"; -static const char *kUnexpectedEnd = "Unexpected end of data"; -static const char *kDataAfterEnd = "There are some data after the end of the payload data"; -static const char *kIsNotArc = "Is not archive"; -static const char *kHeadersError = "Headers Error"; +static const char * const kUnsupportedMethod = "Unsupported Method"; +static const char * const kCRCFailed = "CRC Failed"; +static const char * const kDataError = "Data Error"; +static const char * const kUnavailableData = "Unavailable data"; +static const char * const kUnexpectedEnd = "Unexpected end of data"; +static const char * const kDataAfterEnd = "There are some data after the end of the payload data"; +static const char * const kIsNotArc = "Is not archive"; +static const char * const kHeadersError = "Headers Error"; -class CArchiveExtractCallback: - public IArchiveExtractCallback, - public ICryptoGetTextPassword, - public CMyUnknownImp + +struct CArcTime { -public: - MY_UNKNOWN_IMP1(ICryptoGetTextPassword) + FILETIME FT; + UInt16 Prec; + Byte Ns100; + bool Def; + + CArcTime() + { + Clear(); + } + + void Clear() + { + FT.dwHighDateTime = FT.dwLowDateTime = 0; + Prec = 0; + Ns100 = 0; + Def = false; + } + + bool IsZero() const + { + return FT.dwLowDateTime == 0 && FT.dwHighDateTime == 0 && Ns100 == 0; + } + + int GetNumDigits() const + { + if (Prec == k_PropVar_TimePrec_Unix || + Prec == k_PropVar_TimePrec_DOS) + return 0; + if (Prec == k_PropVar_TimePrec_HighPrec) + return 9; + if (Prec == k_PropVar_TimePrec_0) + return 7; + int digits = (int)Prec - (int)k_PropVar_TimePrec_Base; + if (digits < 0) + digits = 0; + return digits; + } + + void Write_To_FiTime(CFiTime &dest) const + { + #ifdef _WIN32 + dest = FT; + #else + if (FILETIME_To_timespec(FT, dest)) + if ((Prec == k_PropVar_TimePrec_Base + 8 || + Prec == k_PropVar_TimePrec_Base + 9) + && Ns100 != 0) + { + dest.tv_nsec += Ns100; + } + #endif + } + + void Set_From_Prop(const PROPVARIANT &prop) + { + FT = prop.filetime; + unsigned prec = 0; + unsigned ns100 = 0; + const unsigned prec_Temp = prop.wReserved1; + if (prec_Temp != 0 + && prec_Temp <= k_PropVar_TimePrec_1ns + && prop.wReserved3 == 0) + { + const unsigned ns100_Temp = prop.wReserved2; + if (ns100_Temp < 100) + { + ns100 = ns100_Temp; + prec = prec_Temp; + } + } + Prec = (UInt16)prec; + Ns100 = (Byte)ns100; + Def = true; + } +}; - // IProgress - STDMETHOD(SetTotal)(UInt64 size); - STDMETHOD(SetCompleted)(const UInt64 *completeValue); - // IArchiveExtractCallback - STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode); - STDMETHOD(PrepareOperation)(Int32 askExtractMode); - STDMETHOD(SetOperationResult)(Int32 resultEOperationResult); - // ICryptoGetTextPassword - STDMETHOD(CryptoGetTextPassword)(BSTR *aPassword); +class CArchiveExtractCallback Z7_final: + public IArchiveExtractCallback, + public ICryptoGetTextPassword, + public CMyUnknownImp +{ + Z7_IFACES_IMP_UNK_2(IArchiveExtractCallback, ICryptoGetTextPassword) + Z7_IFACE_COM7_IMP(IProgress) -private: CMyComPtr<IInArchive> _archiveHandler; FString _directoryPath; // Output directory UString _filePath; // name inside arcvhive @@ -220,11 +330,10 @@ private: bool _extractMode; struct CProcessedFileInfo { - FILETIME MTime; + CArcTime MTime; UInt32 Attrib; bool isDir; - bool AttribDefined; - bool MTimeDefined; + bool Attrib_Defined; } _processedFileInfo; COutFileStream *_outFileStreamSpec; @@ -248,26 +357,26 @@ void CArchiveExtractCallback::Init(IInArchive *archiveHandler, const FString &di NName::NormalizeDirPathPrefix(_directoryPath); } -STDMETHODIMP CArchiveExtractCallback::SetTotal(UInt64 /* size */) +Z7_COM7F_IMF(CArchiveExtractCallback::SetTotal(UInt64 /* size */)) { return S_OK; } -STDMETHODIMP CArchiveExtractCallback::SetCompleted(const UInt64 * /* completeValue */) +Z7_COM7F_IMF(CArchiveExtractCallback::SetCompleted(const UInt64 * /* completeValue */)) { return S_OK; } -STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, - ISequentialOutStream **outStream, Int32 askExtractMode) +Z7_COM7F_IMF(CArchiveExtractCallback::GetStream(UInt32 index, + ISequentialOutStream **outStream, Int32 askExtractMode)) { - *outStream = 0; + *outStream = NULL; _outFileStream.Release(); { // Get Name NCOM::CPropVariant prop; - RINOK(_archiveHandler->GetProperty(index, kpidPath, &prop)); + RINOK(_archiveHandler->GetProperty(index, kpidPath, &prop)) UString fullPath; if (prop.vt == VT_EMPTY) @@ -287,36 +396,35 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, { // Get Attrib NCOM::CPropVariant prop; - RINOK(_archiveHandler->GetProperty(index, kpidAttrib, &prop)); + RINOK(_archiveHandler->GetProperty(index, kpidAttrib, &prop)) if (prop.vt == VT_EMPTY) { _processedFileInfo.Attrib = 0; - _processedFileInfo.AttribDefined = false; + _processedFileInfo.Attrib_Defined = false; } else { if (prop.vt != VT_UI4) return E_FAIL; _processedFileInfo.Attrib = prop.ulVal; - _processedFileInfo.AttribDefined = true; + _processedFileInfo.Attrib_Defined = true; } } - RINOK(IsArchiveItemFolder(_archiveHandler, index, _processedFileInfo.isDir)); + RINOK(IsArchiveItemFolder(_archiveHandler, index, _processedFileInfo.isDir)) { + _processedFileInfo.MTime.Clear(); // Get Modified Time NCOM::CPropVariant prop; - RINOK(_archiveHandler->GetProperty(index, kpidMTime, &prop)); - _processedFileInfo.MTimeDefined = false; + RINOK(_archiveHandler->GetProperty(index, kpidMTime, &prop)) switch (prop.vt) { case VT_EMPTY: // _processedFileInfo.MTime = _utcMTimeDefault; break; case VT_FILETIME: - _processedFileInfo.MTime = prop.filetime; - _processedFileInfo.MTimeDefined = true; + _processedFileInfo.MTime.Set_From_Prop(prop); break; default: return E_FAIL; @@ -326,7 +434,7 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, { // Get Size NCOM::CPropVariant prop; - RINOK(_archiveHandler->GetProperty(index, kpidSize, &prop)); + RINOK(_archiveHandler->GetProperty(index, kpidSize, &prop)) UInt64 newFileSize; /* bool newFileSizeDefined = */ ConvertPropVariantToUInt64(prop, newFileSize); } @@ -353,7 +461,7 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, { if (!DeleteFileAlways(fullProcessedPath)) { - PrintError("Can not delete output file", fullProcessedPath); + PrintError("Cannot delete output file", fullProcessedPath); return E_ABORT; } } @@ -362,7 +470,7 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec); if (!_outFileStreamSpec->Open(fullProcessedPath, CREATE_ALWAYS)) { - PrintError("Can not open output file", fullProcessedPath); + PrintError("Cannot open output file", fullProcessedPath); return E_ABORT; } _outFileStream = outStreamLoc; @@ -371,24 +479,27 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, return S_OK; } -STDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode) +Z7_COM7F_IMF(CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode)) { _extractMode = false; switch (askExtractMode) { case NArchive::NExtract::NAskMode::kExtract: _extractMode = true; break; - }; + } switch (askExtractMode) { - case NArchive::NExtract::NAskMode::kExtract: PrintString(kExtractingString); break; - case NArchive::NExtract::NAskMode::kTest: PrintString(kTestingString); break; - case NArchive::NExtract::NAskMode::kSkip: PrintString(kSkippingString); break; - }; - PrintString(_filePath); + case NArchive::NExtract::NAskMode::kExtract: Print(kExtractingString); break; + case NArchive::NExtract::NAskMode::kTest: Print(kTestingString); break; + case NArchive::NExtract::NAskMode::kSkip: Print(kSkippingString); break; + case NArchive::NExtract::NAskMode::kReadExternal: Print(kReadingString); break; + default: + Print("??? "); break; + } + Print(_filePath); return S_OK; } -STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult) +Z7_COM7F_IMF(CArchiveExtractCallback::SetOperationResult(Int32 operationResult)) { switch (operationResult) { @@ -397,7 +508,7 @@ STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult) default: { NumErrors++; - PrintString(" : "); + Print(" : "); const char *s = NULL; switch (operationResult) { @@ -428,34 +539,38 @@ STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult) } if (s) { - PrintString("Error : "); - PrintString(s); + Print("Error : "); + Print(s); } else { char temp[16]; - ConvertUInt32ToString(operationResult, temp); - PrintString("Error #"); - PrintString(temp); + ConvertUInt32ToString((UInt32)operationResult, temp); + Print("Error #"); + Print(temp); } } } if (_outFileStream) { - if (_processedFileInfo.MTimeDefined) - _outFileStreamSpec->SetMTime(&_processedFileInfo.MTime); - RINOK(_outFileStreamSpec->Close()); + if (_processedFileInfo.MTime.Def) + { + CFiTime ft; + _processedFileInfo.MTime.Write_To_FiTime(ft); + _outFileStreamSpec->SetMTime(&ft); + } + RINOK(_outFileStreamSpec->Close()) } _outFileStream.Release(); - if (_extractMode && _processedFileInfo.AttribDefined) - SetFileAttrib(_diskFilePath, _processedFileInfo.Attrib); + if (_extractMode && _processedFileInfo.Attrib_Defined) + SetFileAttrib_PosixHighDetect(_diskFilePath, _processedFileInfo.Attrib); PrintNewLine(); return S_OK; } -STDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password) +Z7_COM7F_IMF(CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password)) { if (!PasswordIsDefined) { @@ -473,41 +588,24 @@ STDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password) ////////////////////////////////////////////////////////////// // Archive Creating callback class -struct CDirItem +struct CDirItem: public NWindows::NFile::NFind::CFileInfoBase { - UInt64 Size; - FILETIME CTime; - FILETIME ATime; - FILETIME MTime; - UString Name; - FString FullPath; - UInt32 Attrib; + UString Path_For_Handler; + FString FullPath; // for filesystem - bool isDir() const { return (Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0 ; } + CDirItem(const NWindows::NFile::NFind::CFileInfo &fi): + CFileInfoBase(fi) + {} }; -class CArchiveUpdateCallback: +class CArchiveUpdateCallback Z7_final: public IArchiveUpdateCallback2, public ICryptoGetTextPassword2, public CMyUnknownImp { -public: - MY_UNKNOWN_IMP2(IArchiveUpdateCallback2, ICryptoGetTextPassword2) - - // IProgress - STDMETHOD(SetTotal)(UInt64 size); - STDMETHOD(SetCompleted)(const UInt64 *completeValue); - - // IUpdateCallback2 - STDMETHOD(GetUpdateItemInfo)(UInt32 index, - Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive); - STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream); - STDMETHOD(SetOperationResult)(Int32 operationResult); - STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size); - STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream); - - STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password); + Z7_IFACES_IMP_UNK_2(IArchiveUpdateCallback2, ICryptoGetTextPassword2) + Z7_IFACE_COM7_IMP(IProgress) + Z7_IFACE_COM7_IMP(IArchiveUpdateCallback) public: CRecordVector<UInt64> VolumesSizes; @@ -526,7 +624,11 @@ public: FStringVector FailedFiles; CRecordVector<HRESULT> FailedCodes; - CArchiveUpdateCallback(): PasswordIsDefined(false), AskPassword(false), DirItems(0) {}; + CArchiveUpdateCallback(): + DirItems(NULL), + PasswordIsDefined(false), + AskPassword(false) + {} ~CArchiveUpdateCallback() { Finilize(); } HRESULT Finilize(); @@ -540,18 +642,18 @@ public: } }; -STDMETHODIMP CArchiveUpdateCallback::SetTotal(UInt64 /* size */) +Z7_COM7F_IMF(CArchiveUpdateCallback::SetTotal(UInt64 /* size */)) { return S_OK; } -STDMETHODIMP CArchiveUpdateCallback::SetCompleted(const UInt64 * /* completeValue */) +Z7_COM7F_IMF(CArchiveUpdateCallback::SetCompleted(const UInt64 * /* completeValue */)) { return S_OK; } -STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 /* index */, - Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive) +Z7_COM7F_IMF(CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 /* index */, + Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive)) { if (newData) *newData = BoolToInt(true); @@ -562,7 +664,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 /* index */, return S_OK; } -STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { NCOM::CPropVariant prop; @@ -574,16 +676,17 @@ STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PR } { - const CDirItem &dirItem = (*DirItems)[index]; + const CDirItem &di = (*DirItems)[index]; switch (propID) { - case kpidPath: prop = dirItem.Name; break; - case kpidIsDir: prop = dirItem.isDir(); break; - case kpidSize: prop = dirItem.Size; break; - case kpidAttrib: prop = dirItem.Attrib; break; - case kpidCTime: prop = dirItem.CTime; break; - case kpidATime: prop = dirItem.ATime; break; - case kpidMTime: prop = dirItem.MTime; break; + case kpidPath: prop = di.Path_For_Handler; break; + case kpidIsDir: prop = di.IsDir(); break; + case kpidSize: prop = di.Size; break; + case kpidCTime: PropVariant_SetFrom_FiTime(prop, di.CTime); break; + case kpidATime: PropVariant_SetFrom_FiTime(prop, di.ATime); break; + case kpidMTime: PropVariant_SetFrom_FiTime(prop, di.MTime); break; + case kpidAttrib: prop = (UInt32)di.GetWinAttrib(); break; + case kpidPosixAttrib: prop = (UInt32)di.GetPosixAttrib(); break; } } prop.Detach(value); @@ -602,20 +705,20 @@ HRESULT CArchiveUpdateCallback::Finilize() static void GetStream2(const wchar_t *name) { - PrintString("Compressing "); + Print("Compressing "); if (name[0] == 0) name = kEmptyFileAlias; - PrintString(name); + Print(name); } -STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream) +Z7_COM7F_IMF(CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream)) { - RINOK(Finilize()); + RINOK(Finilize()) const CDirItem &dirItem = (*DirItems)[index]; - GetStream2(dirItem.Name); + GetStream2(dirItem.Path_For_Handler); - if (dirItem.isDir()) + if (dirItem.IsDir()) return S_OK; { @@ -624,14 +727,14 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream FString path = DirPrefix + dirItem.FullPath; if (!inStreamSpec->Open(path)) { - DWORD sysError = ::GetLastError(); - FailedCodes.Add(sysError); + const DWORD sysError = ::GetLastError(); + FailedCodes.Add(HRESULT_FROM_WIN32(sysError)); FailedFiles.Add(path); // if (systemError == ERROR_SHARING_VIOLATION) { PrintNewLine(); PrintError("WARNING: can't open file"); - // PrintString(NError::MyFormatMessageW(systemError)); + // Print(NError::MyFormatMessageW(systemError)); return S_FALSE; } // return sysError; @@ -641,13 +744,13 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream return S_OK; } -STDMETHODIMP CArchiveUpdateCallback::SetOperationResult(Int32 /* operationResult */) +Z7_COM7F_IMF(CArchiveUpdateCallback::SetOperationResult(Int32 /* operationResult */)) { m_NeedBeClosed = true; return S_OK; } -STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size) +Z7_COM7F_IMF(CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size)) { if (VolumesSizes.Size() == 0) return S_FALSE; @@ -657,7 +760,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size) return S_OK; } -STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream) +Z7_COM7F_IMF(CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream)) { wchar_t temp[16]; ConvertUInt32ToString(index + 1, temp); @@ -665,18 +768,18 @@ STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOu while (res.Len() < 2) res.InsertAtFront(L'0'); UString fileName = VolName; - fileName += L'.'; + fileName.Add_Dot(); fileName += res; fileName += VolExt; COutFileStream *streamSpec = new COutFileStream; CMyComPtr<ISequentialOutStream> streamLoc(streamSpec); if (!streamSpec->Create(us2fs(fileName), false)) - return ::GetLastError(); + return GetLastError_noZero_HRESULT(); *volumeStream = streamLoc.Detach(); return S_OK; } -STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) +Z7_COM7F_IMF(CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)) { if (!PasswordIsDefined) { @@ -696,62 +799,118 @@ STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDef // Main function +#if defined(_UNICODE) && !defined(_WIN64) && !defined(UNDER_CE) #define NT_CHECK_FAIL_ACTION PrintError("Unsupported Windows version"); return 1; +#endif -int MY_CDECL main(int numArgs, const char *args[]) +int Z7_CDECL main(int numArgs, const char *args[]) { NT_CHECK + #ifdef ENV_HAVE_LOCALE + MY_SetLocale(); + #endif + PrintStringLn(kCopyrightString); - if (numArgs < 3) + if (numArgs < 2) { PrintStringLn(kHelpString); - return 1; + return 0; } - + + FString dllPrefix; + + #ifdef _WIN32 + dllPrefix = NDLL::GetModuleDirPrefix(); + #else + { + AString s (args[0]); + int sep = s.ReverseFind_PathSepar(); + s.DeleteFrom(sep + 1); + dllPrefix = s; + } + #endif + NDLL::CLibrary lib; - if (!lib.Load(NDLL::GetModuleDirPrefix() + FTEXT(kDllName))) + if (!lib.Load(dllPrefix + FTEXT(kDllName))) { - PrintError("Can not load 7-zip library"); + PrintError("Cannot load 7-zip library"); return 1; } - Func_CreateObject createObjectFunc = (Func_CreateObject)lib.GetProc("CreateObject"); - if (!createObjectFunc) + Func_CreateObject + f_CreateObject = Z7_GET_PROC_ADDRESS( + Func_CreateObject, lib.Get_HMODULE(), + "CreateObject"); + if (!f_CreateObject) { - PrintError("Can not get CreateObject"); + PrintError("Cannot get CreateObject"); return 1; } - char c; + char c = 0; + UString password; + bool passwordIsDefined = false; + CObjectVector<FString> params; + + for (int curCmd = 1; curCmd < numArgs; curCmd++) { - AString command = args[1]; - if (command.Len() != 1) + AString a(args[curCmd]); + + if (!a.IsEmpty()) { - PrintError("incorrect command"); + if (a[0] == '-') + { + if (!passwordIsDefined && a[1] == 'p') + { + password = GetUnicodeString(a.Ptr(2)); + passwordIsDefined = true; + continue; + } + } + else + { + if (c) + { + params.Add(CmdStringToFString(a)); + continue; + } + if (a.Len() == 1) + { + c = (char)MyCharLower_Ascii(a[0]); + continue; + } + } + } + { + PrintError(kIncorrectCommand); return 1; } - c = (char)MyCharLower_Ascii(command[0]); } - FString archiveName = CmdStringToFString(args[2]); + if (!c || params.Size() < 1) + { + PrintError(kIncorrectCommand); + return 1; + } + + const FString &archiveName = params[0]; if (c == 'a') { // create archive command - if (numArgs < 4) + if (params.Size() < 2) { - PrintStringLn(kHelpString); + PrintError(kIncorrectCommand); return 1; } CObjectVector<CDirItem> dirItems; { - int i; - for (i = 3; i < numArgs; i++) + unsigned i; + for (i = 1; i < params.Size(); i++) { - CDirItem di; - FString name = CmdStringToFString(args[i]); + const FString &name = params[i]; NFind::CFileInfo fi; if (!fi.Find(name)) @@ -759,13 +918,10 @@ int MY_CDECL main(int numArgs, const char *args[]) PrintError("Can't find file", name); return 1; } + + CDirItem di(fi); - di.Attrib = fi.Attrib; - di.Size = fi.Size; - di.CTime = fi.CTime; - di.ATime = fi.ATime; - di.MTime = fi.MTime; - di.Name = fs2us(name); + di.Path_For_Handler = fs2us(name); di.FullPath = name; dirItems.Add(di); } @@ -780,28 +936,30 @@ int MY_CDECL main(int numArgs, const char *args[]) } CMyComPtr<IOutArchive> outArchive; - if (createObjectFunc(&CLSID_Format, &IID_IOutArchive, (void **)&outArchive) != S_OK) + if (f_CreateObject(&CLSID_Format, &IID_IOutArchive, (void **)&outArchive) != S_OK) { - PrintError("Can not get class object"); + PrintError("Cannot get class object"); return 1; } CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; CMyComPtr<IArchiveUpdateCallback2> updateCallback(updateCallbackSpec); updateCallbackSpec->Init(&dirItems); - // updateCallbackSpec->PasswordIsDefined = true; - // updateCallbackSpec->Password = L"1"; + updateCallbackSpec->PasswordIsDefined = passwordIsDefined; + updateCallbackSpec->Password = password; /* { const wchar_t *names[] = { + L"m", L"s", L"x" }; - const unsigned kNumProps = ARRAY_SIZE(names); + const unsigned kNumProps = Z7_ARRAY_SIZE(names); NCOM::CPropVariant values[kNumProps] = { + L"lzma", false, // solid mode OFF (UInt32)9 // compression level = 9 - ultra }; @@ -812,7 +970,11 @@ int MY_CDECL main(int numArgs, const char *args[]) PrintError("ISetProperties unsupported"); return 1; } - RINOK(setProperties->SetProperties(names, values, kNumProps)); + if (setProperties->SetProperties(names, values, kNumProps) != S_OK) + { + PrintError("SetProperties() error"); + return 1; + } } */ @@ -837,9 +999,9 @@ int MY_CDECL main(int numArgs, const char *args[]) } else { - if (numArgs != 3) + if (params.Size() != 1) { - PrintStringLn(kHelpString); + PrintError(kIncorrectCommand); return 1; } @@ -851,14 +1013,14 @@ int MY_CDECL main(int numArgs, const char *args[]) listCommand = false; else { - PrintError("incorrect command"); + PrintError(kIncorrectCommand); return 1; } CMyComPtr<IInArchive> archive; - if (createObjectFunc(&CLSID_Format, &IID_IInArchive, (void **)&archive) != S_OK) + if (f_CreateObject(&CLSID_Format, &IID_IInArchive, (void **)&archive) != S_OK) { - PrintError("Can not get class object"); + PrintError("Cannot get class object"); return 1; } @@ -867,21 +1029,20 @@ int MY_CDECL main(int numArgs, const char *args[]) if (!fileSpec->Open(archiveName)) { - PrintError("Can not open archive file", archiveName); + PrintError("Cannot open archive file", archiveName); return 1; } { CArchiveOpenCallback *openCallbackSpec = new CArchiveOpenCallback; CMyComPtr<IArchiveOpenCallback> openCallback(openCallbackSpec); - openCallbackSpec->PasswordIsDefined = false; - // openCallbackSpec->PasswordIsDefined = true; - // openCallbackSpec->Password = L"1"; + openCallbackSpec->PasswordIsDefined = passwordIsDefined; + openCallbackSpec->Password = password; const UInt64 scanSize = 1 << 23; if (archive->Open(file, &scanSize, openCallback) != S_OK) { - PrintError("Can not open file as archive", archiveName); + PrintError("Cannot open file as archive", archiveName); return 1; } } @@ -899,17 +1060,17 @@ int MY_CDECL main(int numArgs, const char *args[]) archive->GetProperty(i, kpidSize, &prop); char s[32]; ConvertPropVariantToShortString(prop, s); - PrintString(s); - PrintString(" "); + Print(s); + Print(" "); } { // Get name of file NCOM::CPropVariant prop; archive->GetProperty(i, kpidPath, &prop); if (prop.vt == VT_BSTR) - PrintString(prop.bstrVal); + Print(prop.bstrVal); else if (prop.vt != VT_EMPTY) - PrintString("ERROR!"); + Print("ERROR!"); } PrintNewLine(); } @@ -919,10 +1080,9 @@ int MY_CDECL main(int numArgs, const char *args[]) // Extract command CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback; CMyComPtr<IArchiveExtractCallback> extractCallback(extractCallbackSpec); - extractCallbackSpec->Init(archive, FTEXT("")); // second parameter is output folder path - extractCallbackSpec->PasswordIsDefined = false; - // extractCallbackSpec->PasswordIsDefined = true; - // extractCallbackSpec->Password = L"1"; + extractCallbackSpec->Init(archive, FString()); // second parameter is output folder path + extractCallbackSpec->PasswordIsDefined = passwordIsDefined; + extractCallbackSpec->Password = password; /* const wchar_t *names[] = @@ -939,7 +1099,13 @@ int MY_CDECL main(int numArgs, const char *args[]) CMyComPtr<ISetProperties> setProperties; archive->QueryInterface(IID_ISetProperties, (void **)&setProperties); if (setProperties) - setProperties->SetProperties(names, values, kNumProps); + { + if (setProperties->SetProperties(names, values, kNumProps) != S_OK) + { + PrintError("SetProperties() error"); + return 1; + } + } */ HRESULT result = archive->Extract(NULL, (UInt32)(Int32)(-1), false, extractCallback); diff --git a/3rdparty/lzma/CPP/7zip/UI/Client7z/Client7z.dsp b/3rdparty/lzma/CPP/7zip/UI/Client7z/Client7z.dsp index 8ad7fb133dd..d46300feb2a 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Client7z/Client7z.dsp +++ b/3rdparty/lzma/CPP/7zip/UI/Client7z/Client7z.dsp @@ -66,7 +66,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c -# ADD CPP /nologo /W4 /WX /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c +# ADD CPP /nologo /MDd /W4 /WX /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c # ADD BASE RSC /l 0x419 /d "_DEBUG" # ADD RSC /l 0x419 /d "_DEBUG" BSC32=bscmake.exe @@ -104,6 +104,10 @@ SOURCE=.\StdAfx.h # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\..\Windows\Defs.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Windows\DLL.cpp # End Source File # Begin Source File @@ -144,6 +148,10 @@ SOURCE=..\..\..\Windows\FileName.h # End Source File # Begin Source File +SOURCE=..\..\..\Windows\NtCheck.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Windows\PropVariant.cpp # End Source File # Begin Source File @@ -158,12 +166,24 @@ SOURCE=..\..\..\Windows\PropVariantConv.cpp SOURCE=..\..\..\Windows\PropVariantConv.h # End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\TimeUtils.h +# End Source File # End Group # Begin Group "Common" # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\..\Common\Common.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Defs.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\IntToString.cpp # End Source File # Begin Source File @@ -172,6 +192,22 @@ SOURCE=..\..\..\Common\IntToString.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\MyBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyCom.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyInitGuid.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyLinux.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\MyString.cpp # End Source File # Begin Source File @@ -180,6 +216,10 @@ SOURCE=..\..\..\Common\MyString.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\MyTypes.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\MyVector.cpp # End Source File # Begin Source File @@ -188,6 +228,10 @@ SOURCE=..\..\..\Common\MyVector.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\MyWindows.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\NewHandler.cpp # End Source File # Begin Source File @@ -222,6 +266,54 @@ SOURCE=..\..\Common\FileStreams.cpp SOURCE=..\..\Common\FileStreams.h # End Source File +# Begin Source File + +SOURCE=..\..\Common\UniqBlocks.h +# End Source File +# End Group +# Begin Group "C" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\..\C\7zTypes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zVersion.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zWindows.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compiler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\CpuArch.h +# End Source File +# End Group +# Begin Group "7zip" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\IDecl.h +# End Source File +# Begin Source File + +SOURCE=..\..\IPassword.h +# End Source File +# Begin Source File + +SOURCE=..\..\IProgress.h +# End Source File +# Begin Source File + +SOURCE=..\..\PropID.h +# End Source File # End Group # Begin Source File @@ -229,7 +321,7 @@ SOURCE=.\Client7z.cpp # End Source File # Begin Source File -SOURCE=..\..\..\..\C\Sort.h +SOURCE=..\..\Archive\IArchive.h # End Source File # End Target # End Project diff --git a/3rdparty/lzma/CPP/7zip/UI/Client7z/StdAfx.h b/3rdparty/lzma/CPP/7zip/UI/Client7z/StdAfx.h index 2854ff3e935..035267ccd02 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Client7z/StdAfx.h +++ b/3rdparty/lzma/CPP/7zip/UI/Client7z/StdAfx.h @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../../Common/Common.h" #endif diff --git a/3rdparty/lzma/CPP/7zip/UI/Client7z/makefile b/3rdparty/lzma/CPP/7zip/UI/Client7z/makefile index 99a6d494778..988701eff6a 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Client7z/makefile +++ b/3rdparty/lzma/CPP/7zip/UI/Client7z/makefile @@ -8,9 +8,9 @@ COMMON_OBJS = \ $O\IntToString.obj \ $O\NewHandler.obj \ $O\MyString.obj \ + $O\MyVector.obj \ $O\StringConvert.obj \ $O\StringToInt.obj \ - $O\MyVector.obj \ $O\Wildcard.obj \ WIN_OBJS = \ diff --git a/3rdparty/lzma/CPP/7zip/UI/Client7z/makefile.gcc b/3rdparty/lzma/CPP/7zip/UI/Client7z/makefile.gcc new file mode 100644 index 00000000000..3f97205d2cf --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/Client7z/makefile.gcc @@ -0,0 +1,69 @@ +PROG = 7zcl +IS_NOT_STANDALONE = 1 + +# IS_X64 = 1 + + + +ifdef SystemDrive +IS_MINGW = 1 +else +ifdef SYSTEMDRIVE +# ifdef OS +IS_MINGW = 1 +endif +endif + + +ifdef IS_MINGW + +SYS_OBJS = \ + $O/resource.o \ + +else + +SYS_OBJS = \ + $O/MyWindows.o \ + $O/TimeUtils.o \ + +endif + + +LOCAL_FLAGS = \ + + +CURRENT_OBJS = \ + $O/Client7z.o \ + +COMMON_OBJS = \ + $O/IntToString.o \ + $O/MyString.o \ + $O/MyVector.o \ + $O/NewHandler.o \ + $O/StringConvert.o \ + $O/StringToInt.o \ + $O/UTFConvert.o \ + $O/Wildcard.o \ + +WIN_OBJS = \ + $O/DLL.o \ + $O/FileDir.o \ + $O/FileFind.o \ + $O/FileIO.o \ + $O/FileName.o \ + $O/PropVariant.o \ + $O/PropVariantConv.o \ + +7ZIP_COMMON_OBJS = \ + $O/FileStreams.o \ + + +OBJS = \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(SYS_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(CURRENT_OBJS) \ + + +include ../../7zip_gcc.mak diff --git a/3rdparty/lzma/CPP/7zip/UI/Client7z/resource.rc b/3rdparty/lzma/CPP/7zip/UI/Client7z/resource.rc index a09bb0441ca..462df6fa752 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Client7z/resource.rc +++ b/3rdparty/lzma/CPP/7zip/UI/Client7z/resource.rc @@ -1,3 +1,3 @@ #include "../../MyVersionInfo.rc" -MY_VERSION_INFO_APP("7-Zip client", "7zcl") +MY_VERSION_INFO_APP("7-Zip client" , "7zcl") diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveCommandLine.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveCommandLine.cpp index 832ec66d9c5..2bdbc418243 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveCommandLine.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveCommandLine.cpp @@ -8,27 +8,53 @@ #ifndef UNDER_CE #include <io.h> #endif +#else +// for isatty() +#include <unistd.h> #endif + #include <stdio.h> +#ifdef Z7_LARGE_PAGES +#include "../../../../C/Alloc.h" +#endif + +#include "../../../Common/IntToString.h" #include "../../../Common/ListFileUtils.h" #include "../../../Common/StringConvert.h" #include "../../../Common/StringToInt.h" +#include "../../../Windows/ErrorMsg.h" #include "../../../Windows/FileDir.h" #include "../../../Windows/FileName.h" +#include "../../../Windows/System.h" #ifdef _WIN32 #include "../../../Windows/FileMapping.h" +#include "../../../Windows/MemoryLock.h" #include "../../../Windows/Synchronization.h" #endif #include "ArchiveCommandLine.h" #include "EnumDirItems.h" -#include "SortUtils.h" #include "Update.h" #include "UpdateAction.h" extern bool g_CaseSensitive; +extern bool g_PathTrailReplaceMode; + +#ifdef Z7_LARGE_PAGES +extern +bool g_LargePagesMode; +bool g_LargePagesMode = false; +#endif + +/* +#ifdef ENV_HAVE_LSTAT +EXTERN_C_BEGIN +extern int global_use_lstat; +EXTERN_C_END +#endif +*/ #ifdef UNDER_CE @@ -36,13 +62,18 @@ extern bool g_CaseSensitive; #else -#if _MSC_VER >= 1400 -#define MY_isatty_fileno(x) _isatty(_fileno(x)) -#else -#define MY_isatty_fileno(x) isatty(fileno(x)) -#endif - -#define MY_IS_TERMINAL(x) (MY_isatty_fileno(x) != 0); +// #define MY_isatty_fileno(x) (isatty(fileno(x))) +// #define MY_IS_TERMINAL(x) (MY_isatty_fileno(x) != 0); +static inline bool MY_IS_TERMINAL(FILE *x) +{ + return ( + #if defined(_MSC_VER) && (_MSC_VER >= 1400) + _isatty(_fileno(x)) + #else + isatty(fileno(x)) + #endif + != 0); +} #endif @@ -59,17 +90,6 @@ static bool StringToUInt32(const wchar_t *s, UInt32 &v) return *end == 0; } -CArcCmdLineException::CArcCmdLineException(const char *a, const wchar_t *u) -{ - (*this) += MultiByteToUnicodeString(a); - if (u) - { - this->Add_LF(); - (*this) += u; - } -} - -int g_CodePage = -1; namespace NKey { enum Enum @@ -113,6 +133,8 @@ enum Enum kSfx, kEmail, kHash, + // kHashGenFile, + kHashDir, kStdIn, kStdOut, @@ -121,26 +143,38 @@ enum Enum kListfileCharSet, kConsoleCharSet, kTechMode, + kListFields, + kPreserveATime, kShareForWrite, + kStopAfterOpenError, kCaseSensitive, kArcNameMode, + kUseSlashMark, kDisableWildcardParsing, kElimDup, kFullPathMode, kHardLinks, + kSymLinks_AllowDangerous, kSymLinks, kNtSecurity, + + kStoreOwnerId, + kStoreOwnerName, + + kZoneFile, kAltStreams, kReplaceColonForAltStream, kWriteToAltStreamIfColon, + kNameTrailReplace, + kDeleteAfterCompressing, kSetArcMTime - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO , kPassword #endif }; @@ -149,13 +183,13 @@ enum Enum static const wchar_t kRecursedIDChar = 'r'; -static const char *kRecursedPostCharSet = "0-"; +static const char * const kRecursedPostCharSet = "0-"; -static const char *k_ArcNameMode_PostCharSet = "sea"; +static const char * const k_ArcNameMode_PostCharSet = "sea"; -static const char *k_Stream_PostCharSet = "012"; +static const char * const k_Stream_PostCharSet = "012"; -static inline const EArcNameMode ParseArcNameMode(int postCharIndex) +static inline EArcNameMode ParseArcNameMode(int postCharIndex) { switch (postCharIndex) { @@ -173,14 +207,17 @@ namespace NRecursedPostCharIndex { }; } -static const char kImmediateNameID = '!'; -static const char kMapNameID = '#'; -static const char kFileListID = '@'; +// static const char +#define kImmediateNameID '!' +#ifdef _WIN32 +#define kMapNameID '#' +#endif +#define kFileListID '@' -static const char kSomeCludePostStringMinSize = 2; // at least <@|!><N>ame must be -static const char kSomeCludeAfterRecursedPostStringMinSize = 2; // at least <@|!><N>ame must be +static const Byte kSomeCludePostStringMinSize = 2; // at least <@|!><N>ame must be +static const Byte kSomeCludeAfterRecursedPostStringMinSize = 2; // at least <@|!><N>ame must be -static const char *kOverwritePostCharSet = "asut"; +static const char * const kOverwritePostCharSet = "asut"; static const NExtract::NOverwriteMode::EEnum k_OverwriteModes[] = { @@ -190,125 +227,154 @@ static const NExtract::NOverwriteMode::EEnum k_OverwriteModes[] = NExtract::NOverwriteMode::kRenameExisting }; + + +#define SWFRM_3(t, mu, mi) t, mu, mi, NULL + +#define SWFRM_1(t) SWFRM_3(t, false, 0) +#define SWFRM_SIMPLE SWFRM_1(NSwitchType::kSimple) +#define SWFRM_MINUS SWFRM_1(NSwitchType::kMinus) +#define SWFRM_STRING SWFRM_1(NSwitchType::kString) + +#define SWFRM_STRING_SINGL(mi) SWFRM_3(NSwitchType::kString, false, mi) +#define SWFRM_STRING_MULT(mi) SWFRM_3(NSwitchType::kString, true, mi) + + static const CSwitchForm kSwitchForms[] = { - { "?" }, - { "h" }, - { "-help" }, + { "?", SWFRM_SIMPLE }, + { "h", SWFRM_SIMPLE }, + { "-help", SWFRM_SIMPLE }, - { "ba" }, - { "bd" }, - { "bt" }, - { "bb", NSwitchType::kString, false, 0 }, + { "ba", SWFRM_SIMPLE }, + { "bd", SWFRM_SIMPLE }, + { "bt", SWFRM_SIMPLE }, + { "bb", SWFRM_STRING_SINGL(0) }, { "bso", NSwitchType::kChar, false, 1, k_Stream_PostCharSet }, { "bse", NSwitchType::kChar, false, 1, k_Stream_PostCharSet }, { "bsp", NSwitchType::kChar, false, 1, k_Stream_PostCharSet }, - { "y" }, + { "y", SWFRM_SIMPLE }, - { "ad" }, + { "ad", SWFRM_SIMPLE }, { "ao", NSwitchType::kChar, false, 1, kOverwritePostCharSet}, - { "t", NSwitchType::kString, false, 1 }, - { "stx", NSwitchType::kString, true, 1 }, + { "t", SWFRM_STRING_SINGL(1) }, + { "stx", SWFRM_STRING_MULT(1) }, - { "m", NSwitchType::kString, true, 1 }, - { "o", NSwitchType::kString, false, 1 }, - { "w", NSwitchType::kString }, - - { "i", NSwitchType::kString, true, kSomeCludePostStringMinSize}, - { "x", NSwitchType::kString, true, kSomeCludePostStringMinSize}, - { "ai", NSwitchType::kString, true, kSomeCludePostStringMinSize}, - { "ax", NSwitchType::kString, true, kSomeCludePostStringMinSize}, - { "an" }, + { "m", SWFRM_STRING_MULT(1) }, + { "o", SWFRM_STRING_SINGL(1) }, + { "w", SWFRM_STRING }, + + { "i", SWFRM_STRING_MULT(kSomeCludePostStringMinSize) }, + { "x", SWFRM_STRING_MULT(kSomeCludePostStringMinSize) }, + { "ai", SWFRM_STRING_MULT(kSomeCludePostStringMinSize) }, + { "ax", SWFRM_STRING_MULT(kSomeCludePostStringMinSize) }, + { "an", SWFRM_SIMPLE }, - { "u", NSwitchType::kString, true, 1}, - { "v", NSwitchType::kString, true, 1}, + { "u", SWFRM_STRING_MULT(1) }, + { "v", SWFRM_STRING_MULT(1) }, { "r", NSwitchType::kChar, false, 0, kRecursedPostCharSet }, - { "stm", NSwitchType::kString }, - { "sfx", NSwitchType::kString }, - { "seml", NSwitchType::kString, false, 0}, - { "scrc", NSwitchType::kString, true, 0 }, + { "stm", SWFRM_STRING }, + { "sfx", SWFRM_STRING }, + { "seml", SWFRM_STRING_SINGL(0) }, + { "scrc", SWFRM_STRING_MULT(0) }, + // { "scrf", SWFRM_STRING_SINGL(1) }, + { "shd", SWFRM_STRING_SINGL(1) }, - { "si", NSwitchType::kString }, - { "so" }, - - { "slp", NSwitchType::kMinus }, - { "scs", NSwitchType::kString }, - { "scc", NSwitchType::kString }, - { "slt" }, - - { "ssw" }, - { "ssc", NSwitchType::kMinus }, + { "si", SWFRM_STRING }, + { "so", SWFRM_SIMPLE }, + + { "slp", SWFRM_STRING }, + { "scs", SWFRM_STRING }, + { "scc", SWFRM_STRING }, + { "slt", SWFRM_SIMPLE }, + { "slf", SWFRM_STRING_SINGL(1) }, + + { "ssp", SWFRM_SIMPLE }, + { "ssw", SWFRM_SIMPLE }, + { "sse", SWFRM_SIMPLE }, + { "ssc", SWFRM_MINUS }, { "sa", NSwitchType::kChar, false, 1, k_ArcNameMode_PostCharSet }, - { "spd" }, - { "spe", NSwitchType::kMinus }, - { "spf", NSwitchType::kString, false, 0 }, + { "spm", SWFRM_STRING_SINGL(0) }, + { "spd", SWFRM_SIMPLE }, + { "spe", SWFRM_MINUS }, + { "spf", SWFRM_STRING_SINGL(0) }, - { "snh", NSwitchType::kMinus }, - { "snl", NSwitchType::kMinus }, - { "sni" }, - { "sns", NSwitchType::kMinus }, - { "snr" }, - { "snc" }, + { "snh", SWFRM_MINUS }, + { "snld", SWFRM_MINUS }, + { "snl", SWFRM_MINUS }, + { "sni", SWFRM_SIMPLE }, + + { "snoi", SWFRM_MINUS }, + { "snon", SWFRM_MINUS }, - { "sdel" }, - { "stl" } + { "snz", SWFRM_STRING_SINGL(0) }, + { "sns", SWFRM_MINUS }, + { "snr", SWFRM_SIMPLE }, + { "snc", SWFRM_SIMPLE }, + + { "snt", SWFRM_MINUS }, + + { "sdel", SWFRM_SIMPLE }, + { "stl", SWFRM_SIMPLE } - #ifndef _NO_CRYPTO - , { "p", NSwitchType::kString } + #ifndef Z7_NO_CRYPTO + , { "p", SWFRM_STRING } #endif }; -static const wchar_t *kUniversalWildcard = L"*"; +static const char * const kUniversalWildcard = "*"; static const unsigned kMinNonSwitchWords = 1; static const unsigned kCommandIndex = 0; -// static const char *kUserErrorMessage = "Incorrect command line"; -static const char *kCannotFindListFile = "Cannot find listfile"; -static const char *kIncorrectListFile = "Incorrect item in listfile.\nCheck charset encoding and -scs switch."; -static const char *kTerminalOutError = "I won't write compressed data to a terminal"; -static const char *kSameTerminalError = "I won't write data and program's messages to same stream"; -static const char *kEmptyFilePath = "Empty file path"; -static const char *kCannotFindArchive = "Cannot find archive"; +// static const char * const kUserErrorMessage = "Incorrect command line"; +// static const char * const kCannotFindListFile = "Cannot find listfile"; +static const char * const kIncorrectListFile = "Incorrect item in listfile.\nCheck charset encoding and -scs switch."; +static const char * const kTerminalOutError = "I won't write compressed data to a terminal"; +static const char * const kSameTerminalError = "I won't write data and program's messages to same stream"; +static const char * const kEmptyFilePath = "Empty file path"; bool CArcCommand::IsFromExtractGroup() const { - switch (CommandType) + switch ((int)CommandType) { case NCommandType::kTest: case NCommandType::kExtract: case NCommandType::kExtractFull: return true; + default: + return false; } - return false; } NExtract::NPathMode::EEnum CArcCommand::GetPathMode() const { - switch (CommandType) + switch ((int)CommandType) { case NCommandType::kTest: case NCommandType::kExtractFull: return NExtract::NPathMode::kFullPaths; + default: + return NExtract::NPathMode::kNoPaths; } - return NExtract::NPathMode::kNoPaths; } bool CArcCommand::IsFromUpdateGroup() const { - switch (CommandType) + switch ((int)CommandType) { case NCommandType::kAdd: case NCommandType::kUpdate: case NCommandType::kDelete: case NCommandType::kRename: return true; + default: + return false; } - return false; } static NRecursedType::EEnum GetRecursedTypeFromIndex(int index) @@ -328,7 +394,7 @@ static const char *g_Commands = "audtexlbih"; static bool ParseArchiveCommand(const UString &commandString, CArcCommand &command) { - UString s = commandString; + UString s (commandString); s.MakeLower_Ascii(); if (s.Len() == 1) { @@ -351,12 +417,28 @@ static bool ParseArchiveCommand(const UString &commandString, CArcCommand &comma // ------------------------------------------------------------------ // filenames functions +struct CNameOption +{ + bool Include; + bool WildcardMatching; + Byte MarkMode; + NRecursedType::EEnum RecursedType; + + CNameOption(): + Include(true), + WildcardMatching(true), + MarkMode(NWildcard::kMark_FileOrDir), + RecursedType(NRecursedType::kNonRecursed) + {} +}; + + static void AddNameToCensor(NWildcard::CCensor &censor, - const UString &name, bool include, NRecursedType::EEnum type, bool wildcardMatching) + const CNameOption &nop, const UString &name) { bool recursed = false; - switch (type) + switch ((int)nop.RecursedType) { case NRecursedType::kWildcardOnlyRecursed: recursed = DoesNameContainWildcard(name); @@ -364,8 +446,15 @@ static void AddNameToCensor(NWildcard::CCensor &censor, case NRecursedType::kRecursed: recursed = true; break; + default: + break; } - censor.AddPreItem(include, name, recursed, wildcardMatching); + + NWildcard::CCensorPathProps props; + props.Recursive = recursed; + props.WildcardMatching = nop.WildcardMatching; + props.MarkMode = nop.MarkMode; + censor.AddPreItem(nop.Include, name, props); } static void AddRenamePair(CObjectVector<CRenamePair> *renamePairs, @@ -386,9 +475,9 @@ static void AddRenamePair(CObjectVector<CRenamePair> *renamePairs, val += pair.NewName; val.Add_LF(); if (type == NRecursedType::kRecursed) - val.AddAscii("-r"); + val += "-r"; else if (type == NRecursedType::kWildcardOnlyRecursed) - val.AddAscii("-r0"); + val += "-r0"; throw CArcCmdLineException("Unsupported rename command:", val); } } @@ -396,13 +485,26 @@ static void AddRenamePair(CObjectVector<CRenamePair> *renamePairs, static void AddToCensorFromListFile( CObjectVector<CRenamePair> *renamePairs, NWildcard::CCensor &censor, - LPCWSTR fileName, bool include, NRecursedType::EEnum type, bool wildcardMatching, Int32 codePage) + const CNameOption &nop, LPCWSTR fileName, UInt32 codePage) { UStringVector names; - if (!NFind::DoesFileExist(us2fs(fileName))) + /* + if (!NFind::DoesFileExist_FollowLink(us2fs(fileName))) throw CArcCmdLineException(kCannotFindListFile, fileName); - if (!ReadNamesFromListFile(us2fs(fileName), names, codePage)) + */ + DWORD lastError = 0; + if (!ReadNamesFromListFile2(us2fs(fileName), names, codePage, lastError)) + { + if (lastError != 0) + { + UString m; + m = "The file operation error for listfile"; + m.Add_LF(); + m += NError::MyFormatMessage(lastError); + throw CArcCmdLineException(m, fileName); + } throw CArcCmdLineException(kIncorrectListFile, fileName); + } if (renamePairs) { if ((names.Size() & 1) != 0) @@ -410,55 +512,73 @@ static void AddToCensorFromListFile( for (unsigned i = 0; i < names.Size(); i += 2) { // change type !!!! - AddRenamePair(renamePairs, names[i], names[i + 1], type, wildcardMatching); + AddRenamePair(renamePairs, names[i], names[i + 1], nop.RecursedType, nop.WildcardMatching); } } else FOR_VECTOR (i, names) - AddNameToCensor(censor, names[i], include, type, wildcardMatching); + AddNameToCensor(censor, nop, names[i]); } static void AddToCensorFromNonSwitchesStrings( CObjectVector<CRenamePair> *renamePairs, unsigned startIndex, NWildcard::CCensor &censor, - const UStringVector &nonSwitchStrings, NRecursedType::EEnum type, - bool wildcardMatching, - bool thereAreSwitchIncludes, Int32 codePage) + const UStringVector &nonSwitchStrings, + int stopSwitchIndex, + const CNameOption &nop, + bool thereAreSwitchIncludes, UInt32 codePage) { + // another default if ((renamePairs || nonSwitchStrings.Size() == startIndex) && !thereAreSwitchIncludes) - AddNameToCensor(censor, kUniversalWildcard, true, type, - true // wildcardMatching - ); + { + /* for rename command: -i switch sets the mask for archive item reading. + if (thereAreSwitchIncludes), { we don't use UniversalWildcard. } + also for non-rename command: we set UniversalWildcard, only if there are no nonSwitches. */ + // we use default fileds in (CNameOption) for UniversalWildcard. + CNameOption nop2; + // recursive mode is not important for UniversalWildcard (*) + // nop2.RecursedType = nop.RecursedType; // we don't need it + /* + nop2.RecursedType = NRecursedType::kNonRecursed; + nop2.Include = true; + nop2.WildcardMatching = true; + nop2.MarkMode = NWildcard::kMark_FileOrDir; + */ + AddNameToCensor(censor, nop2, UString(kUniversalWildcard)); + } int oldIndex = -1; + if (stopSwitchIndex < 0) + stopSwitchIndex = (int)nonSwitchStrings.Size(); + for (unsigned i = startIndex; i < nonSwitchStrings.Size(); i++) { const UString &s = nonSwitchStrings[i]; if (s.IsEmpty()) throw CArcCmdLineException(kEmptyFilePath); - if (s[0] == kFileListID) - AddToCensorFromListFile(renamePairs, censor, s.Ptr(1), true, type, wildcardMatching, codePage); + if (i < (unsigned)stopSwitchIndex && s[0] == kFileListID) + AddToCensorFromListFile(renamePairs, censor, nop, s.Ptr(1), codePage); else if (renamePairs) { if (oldIndex == -1) - oldIndex = i; + oldIndex = (int)i; else { // NRecursedType::EEnum type is used for global wildcard (-i! switches) - AddRenamePair(renamePairs, nonSwitchStrings[oldIndex], s, NRecursedType::kNonRecursed, wildcardMatching); + AddRenamePair(renamePairs, nonSwitchStrings[(unsigned)oldIndex], s, NRecursedType::kNonRecursed, nop.WildcardMatching); // AddRenamePair(renamePairs, nonSwitchStrings[oldIndex], s, type); oldIndex = -1; } } else - AddNameToCensor(censor, s, true, type, wildcardMatching); + AddNameToCensor(censor, nop, s); } if (oldIndex != -1) { - throw CArcCmdLineException("There is no second file name for rename pair:", nonSwitchStrings[oldIndex]); + throw CArcCmdLineException("There is no second file name for rename pair:", nonSwitchStrings[(unsigned)oldIndex]); } } @@ -477,35 +597,34 @@ struct CEventSetEnd } }; -const char *k_IncorrectMapCommand = "Incorrect Map command"; +static const char * const k_IncorrectMapCommand = "Incorrect Map command"; static const char *ParseMapWithPaths( NWildcard::CCensor &censor, - const UString &s2, bool include, - NRecursedType::EEnum commonRecursedType, - bool wildcardMatching) + const UString &s2, + const CNameOption &nop) { - UString s = s2; + UString s (s2); int pos = s.Find(L':'); if (pos < 0) return k_IncorrectMapCommand; - int pos2 = s.Find(L':', pos + 1); + int pos2 = s.Find(L':', (unsigned)(pos + 1)); if (pos2 < 0) return k_IncorrectMapCommand; - CEventSetEnd eventSetEnd((const wchar_t *)s + ((unsigned)pos2 + 1)); - s.DeleteFrom(pos2); + CEventSetEnd eventSetEnd((const wchar_t *)s + (unsigned)(pos2 + 1)); + s.DeleteFrom((unsigned)pos2); UInt32 size; - if (!StringToUInt32(s.Ptr(pos + 1), size) + if (!StringToUInt32(s.Ptr((unsigned)(pos + 1)), size) || size < sizeof(wchar_t) || size > ((UInt32)1 << 31) || size % sizeof(wchar_t) != 0) return "Unsupported Map data size"; - s.DeleteFrom(pos); + s.DeleteFrom((unsigned)pos); CFileMapping map; if (map.Open(FILE_MAP_READ, GetSystemString(s)) != 0) - return "Can not open mapping"; + return "Cannot open mapping"; LPVOID data = map.Map(FILE_MAP_READ, 0, size); if (!data) return "MapViewOfFile error"; @@ -522,7 +641,7 @@ static const char *ParseMapWithPaths( if (c == 0) { // MessageBoxW(0, name, L"7-Zip", 0); - AddNameToCensor(censor, name, include, commonRecursedType, wildcardMatching); + AddNameToCensor(censor, nop, name); name.Empty(); } else @@ -538,17 +657,15 @@ static const char *ParseMapWithPaths( static void AddSwitchWildcardsToCensor( NWildcard::CCensor &censor, - const UStringVector &strings, bool include, - NRecursedType::EEnum commonRecursedType, - bool wildcardMatching, - Int32 codePage) + const UStringVector &strings, + const CNameOption &nop, + UInt32 codePage) { const char *errorMessage = NULL; unsigned i; for (i = 0; i < strings.Size(); i++) { const UString &name = strings[i]; - NRecursedType::EEnum recursedType; unsigned pos = 0; if (name.Len() < kSomeCludePostStringMinSize) @@ -556,37 +673,118 @@ static void AddSwitchWildcardsToCensor( errorMessage = "Too short switch"; break; } - - if (::MyCharLower_Ascii(name[pos]) == kRecursedIDChar) + + if (!nop.Include) { - pos++; - wchar_t c = name[pos]; - int index = -1; - if (c <= 0x7F) - index = FindCharPosInString(kRecursedPostCharSet, (char)c); - recursedType = GetRecursedTypeFromIndex(index); - if (index >= 0) + if (name.IsEqualTo_Ascii_NoCase("td")) + { + censor.ExcludeDirItems = true; + continue; + } + if (name.IsEqualTo_Ascii_NoCase("tf")) + { + censor.ExcludeFileItems = true; + continue; + } + } + + CNameOption nop2 = nop; + + bool type_WasUsed = false; + bool recursed_WasUsed = false; + bool matching_WasUsed = false; + bool error = false; + + for (;;) + { + wchar_t c = ::MyCharLower_Ascii(name[pos]); + if (c == kRecursedIDChar) + { + if (recursed_WasUsed) + { + error = true; + break; + } + recursed_WasUsed = true; + pos++; + c = name[pos]; + int index = -1; + if (c <= 0x7F) + index = FindCharPosInString(kRecursedPostCharSet, (char)c); + nop2.RecursedType = GetRecursedTypeFromIndex(index); + if (index >= 0) + { + pos++; + continue; + } + } + + if (c == 'w') + { + if (matching_WasUsed) + { + error = true; + break; + } + matching_WasUsed = true; + nop2.WildcardMatching = true; pos++; + if (name[pos] == '-') + { + nop2.WildcardMatching = false; + pos++; + } + } + else if (c == 'm') + { + if (type_WasUsed) + { + error = true; + break; + } + type_WasUsed = true; + pos++; + nop2.MarkMode = NWildcard::kMark_StrictFile; + c = name[pos]; + if (c == '-') + { + nop2.MarkMode = NWildcard::kMark_FileOrDir; + pos++; + } + else if (c == '2') + { + nop2.MarkMode = NWildcard::kMark_StrictFile_IfWildcard; + pos++; + } + } + else + break; } - else - recursedType = commonRecursedType; + if (error) + { + errorMessage = "inorrect switch"; + break; + } + if (name.Len() < pos + kSomeCludeAfterRecursedPostStringMinSize) { errorMessage = "Too short switch"; break; } - UString tail = name.Ptr(pos + 1); - - if (name[pos] == kImmediateNameID) - AddNameToCensor(censor, tail, include, recursedType, wildcardMatching); - else if (name[pos] == kFileListID) - AddToCensorFromListFile(NULL, censor, tail, include, recursedType, wildcardMatching, codePage); + const UString tail = name.Ptr(pos + 1); + + const wchar_t c = name[pos]; + + if (c == kImmediateNameID) + AddNameToCensor(censor, nop2, tail); + else if (c == kFileListID) + AddToCensorFromListFile(NULL, censor, nop2, tail, codePage); #ifdef _WIN32 - else if (name[pos] == kMapNameID) + else if (c == kMapNameID) { - errorMessage = ParseMapWithPaths(censor, tail, include, recursedType, wildcardMatching); + errorMessage = ParseMapWithPaths(censor, tail, nop2); if (errorMessage) break; } @@ -597,88 +795,11 @@ static void AddSwitchWildcardsToCensor( break; } } + if (i != strings.Size()) throw CArcCmdLineException(errorMessage, strings[i]); } -#ifdef _WIN32 - -// This code converts all short file names to long file names. - -static void ConvertToLongName(const UString &prefix, UString &name) -{ - if (name.IsEmpty() || DoesNameContainWildcard(name)) - return; - NFind::CFileInfo fi; - const FString path = us2fs(prefix + name); - #ifndef UNDER_CE - if (NFile::NName::IsDevicePath(path)) - return; - #endif - if (fi.Find(path)) - name = fs2us(fi.Name); -} - -static void ConvertToLongNames(const UString &prefix, CObjectVector<NWildcard::CItem> &items) -{ - FOR_VECTOR (i, items) - { - NWildcard::CItem &item = items[i]; - if (item.Recursive || item.PathParts.Size() != 1) - continue; - if (prefix.IsEmpty() && item.IsDriveItem()) - continue; - ConvertToLongName(prefix, item.PathParts.Front()); - } -} - -static void ConvertToLongNames(const UString &prefix, NWildcard::CCensorNode &node) -{ - ConvertToLongNames(prefix, node.IncludeItems); - ConvertToLongNames(prefix, node.ExcludeItems); - unsigned i; - for (i = 0; i < node.SubNodes.Size(); i++) - { - UString &name = node.SubNodes[i].Name; - if (prefix.IsEmpty() && NWildcard::IsDriveColonName(name)) - continue; - ConvertToLongName(prefix, name); - } - // mix folders with same name - for (i = 0; i < node.SubNodes.Size(); i++) - { - NWildcard::CCensorNode &nextNode1 = node.SubNodes[i]; - for (unsigned j = i + 1; j < node.SubNodes.Size();) - { - const NWildcard::CCensorNode &nextNode2 = node.SubNodes[j]; - if (nextNode1.Name.IsEqualTo_NoCase(nextNode2.Name)) - { - nextNode1.IncludeItems += nextNode2.IncludeItems; - nextNode1.ExcludeItems += nextNode2.ExcludeItems; - node.SubNodes.Delete(j); - } - else - j++; - } - } - for (i = 0; i < node.SubNodes.Size(); i++) - { - NWildcard::CCensorNode &nextNode = node.SubNodes[i]; - ConvertToLongNames(prefix + nextNode.Name + WCHAR_PATH_SEPARATOR, nextNode); - } -} - -void ConvertToLongNames(NWildcard::CCensor &censor) -{ - FOR_VECTOR (i, censor.Pairs) - { - NWildcard::CPair &pair = censor.Pairs[i]; - ConvertToLongNames(pair.Prefix, pair.Head); - } -} - -#endif - /* static NUpdateArchive::NPairAction::EEnum GetUpdatePairActionType(int i) { @@ -693,11 +814,11 @@ static NUpdateArchive::NPairAction::EEnum GetUpdatePairActionType(int i) } */ -static const wchar_t *kUpdatePairStateIDSet = L"pqrxyzw"; +static const char * const kUpdatePairStateIDSet = "pqrxyzw"; static const int kUpdatePairStateNotSupportedActions[] = {2, 2, 1, -1, -1, -1, -1}; static const unsigned kNumUpdatePairActions = 4; -static const char *kUpdateIgnoreItselfPostStringID = "-"; +static const char * const kUpdateIgnoreItselfPostStringID = "-"; static const wchar_t kUpdateNewArchivePostCharID = '!'; @@ -707,8 +828,8 @@ static bool ParseUpdateCommandString2(const UString &command, for (unsigned i = 0; i < command.Len();) { wchar_t c = MyCharLower_Ascii(command[i]); - int statePos = FindCharPosInString(kUpdatePairStateIDSet, c); - if (statePos < 0) + int statePos = FindCharPosInString(kUpdatePairStateIDSet, (char)c); + if (c > 0x7F || statePos < 0) { postString = command.Ptr(i); return true; @@ -717,9 +838,9 @@ static bool ParseUpdateCommandString2(const UString &command, if (i >= command.Len()) return false; c = command[i]; - if (c < '0' || c >= '0' + kNumUpdatePairActions) + if (c < '0' || c >= (wchar_t)('0' + kNumUpdatePairActions)) return false; - unsigned actionPos = c - '0'; + unsigned actionPos = (unsigned)(c - '0'); actionSet.StateActions[(unsigned)statePos] = (NUpdateArchive::NPairAction::EEnum)(actionPos); if (kUpdatePairStateNotSupportedActions[(unsigned)statePos] == (int)actionPos) return false; @@ -784,7 +905,7 @@ static void SetAddCommandOptions( CUpdateOptions &options) { NUpdateArchive::CActionSet defaultActionSet; - switch (commandType) + switch ((int)commandType) { case NCommandType::kAdd: defaultActionSet = NUpdateArchive::k_ActionSet_Add; @@ -823,8 +944,10 @@ static void SetAddCommandOptions( FOR_VECTOR (i, sv) { UInt64 size; - if (!ParseComplexSize(sv[i], size) || size == 0) + if (!ParseComplexSize(sv[i], size)) throw CArcCmdLineException("Incorrect volume size:", sv[i]); + if (i == sv.Size() - 1 && size == 0) + throw CArcCmdLineException("zero size last volume is not allowed"); options.VolumesSizes.Add(size); } } @@ -841,26 +964,37 @@ static void SetMethodOptions(const CParser &parser, CObjectVector<CProperty> &pr int index = prop.Name.Find(L'='); if (index >= 0) { - prop.Value = prop.Name.Ptr(index + 1); - prop.Name.DeleteFrom(index); + prop.Value = prop.Name.Ptr((unsigned)(index + 1)); + prop.Name.DeleteFrom((unsigned)index); } properties.Add(prop); } } } -CArcCmdLineParser::CArcCmdLineParser(): parser(ARRAY_SIZE(kSwitchForms)) {} static inline void SetStreamMode(const CSwitchResult &sw, unsigned &res) { if (sw.ThereIs) - res = sw.PostCharIndex; + res = (unsigned)sw.PostCharIndex; } + +#if defined(_WIN32) && !defined(UNDER_CE) +static void PrintHex(UString &s, UInt64 v) +{ + char temp[32]; + ConvertUInt64ToHex(v, temp); + s += temp; +} +#endif + + void CArcCmdLineParser::Parse1(const UStringVector &commandStrings, CArcCmdLineOptions &options) { - if (!parser.ParseStrings(kSwitchForms, commandStrings)) + Parse1Log.Empty(); + if (!parser.ParseStrings(kSwitchForms, Z7_ARRAY_SIZE(kSwitchForms), commandStrings)) throw CArcCmdLineException(parser.ErrorMessage, parser.ErrorLine); options.IsInTerminal = MY_IS_TERMINAL(stdin); @@ -872,6 +1006,11 @@ void CArcCmdLineParser::Parse1(const UStringVector &commandStrings, options.StdInMode = parser[NKey::kStdIn].ThereIs; options.StdOutMode = parser[NKey::kStdOut].ThereIs; options.EnableHeaders = !parser[NKey::kDisableHeaders].ThereIs; + if (parser[NKey::kListFields].ThereIs) + { + const UString &s = parser[NKey::kListFields].PostStrings[0]; + options.ListFields = GetAnsiString(s); + } options.TechMode = parser[NKey::kTechMode].ThereIs; options.ShowTime = parser[NKey::kShowTime].ThereIs; @@ -903,14 +1042,52 @@ void CArcCmdLineParser::Parse1(const UStringVector &commandStrings, if (parser[NKey::kCaseSensitive].ThereIs) { + options.CaseSensitive = g_CaseSensitive = !parser[NKey::kCaseSensitive].WithMinus; - options.CaseSensitiveChange = true; - options.CaseSensitive = g_CaseSensitive; + options.CaseSensitive_Change = true; } - options.LargePages = false; + + #if defined(_WIN32) && !defined(UNDER_CE) + NSecurity::EnablePrivilege_SymLink(); + #endif + + // options.LargePages = false; + if (parser[NKey::kLargePages].ThereIs) - options.LargePages = !parser[NKey::kLargePages].WithMinus; + { + UInt32 slp = 0; + const UString &s = parser[NKey::kLargePages].PostStrings[0]; + if (s.IsEmpty()) + slp = 1; + else if (s != L"-") + { + if (!StringToUInt32(s, slp)) + throw CArcCmdLineException("Unsupported switch postfix for -slp", s); + } + + #ifdef Z7_LARGE_PAGES + if (slp > + #if defined(_WIN32) && !defined(UNDER_CE) + (unsigned)NSecurity::Get_LargePages_RiskLevel() + #else + 0 + #endif + ) + { + #ifdef _WIN32 // change it ! + SetLargePageSize(); + #endif + // note: this process also can inherit that Privilege from parent process + g_LargePagesMode = + #if defined(_WIN32) && !defined(UNDER_CE) + NSecurity::EnablePrivilege_LockMemory(); + #else + true; + #endif + } + #endif + } #ifndef UNDER_CE @@ -920,32 +1097,83 @@ void CArcCmdLineParser::Parse1(const UStringVector &commandStrings, const UString &s = parser[NKey::kAffinity].PostStrings[0]; if (!s.IsEmpty()) { - UInt32 v = 0; AString a; a.SetFromWStr_if_Ascii(s); - if (!a.IsEmpty()) + Parse1Log += "Set process affinity mask: "; + + #ifdef _WIN32 + + UInt64 v = 0; { const char *end; - v = ConvertHexStringToUInt32(a, &end); + v = ConvertHexStringToUInt64(a, &end); if (*end != 0) a.Empty(); } if (a.IsEmpty()) throw CArcCmdLineException("Unsupported switch postfix -stm", s); + + { + #ifndef _WIN64 + if (v >= ((UInt64)1 << 32)) + throw CArcCmdLineException("unsupported value -stm", s); + #endif + { + PrintHex(Parse1Log, v); + if (!SetProcessAffinityMask(GetCurrentProcess(), (DWORD_PTR)v)) + { + DWORD lastError = GetLastError(); + Parse1Log += " : ERROR : "; + Parse1Log += NError::MyFormatMessage(lastError); + } + } + } - #ifdef _WIN32 - SetProcessAffinityMask(GetCurrentProcess(), v); - #endif + #else // _WIN32 + + { + Parse1Log += a; + NSystem::CProcessAffinity aff; + aff.CpuZero(); + for (unsigned i = 0; i < a.Len(); i++) + { + char c = a[i]; + unsigned v; + if (c >= '0' && c <= '9') v = (unsigned)(c - '0'); + else if (c >= 'A' && c <= 'F') v = 10 + (unsigned)(c - 'A'); + else if (c >= 'a' && c <= 'f') v = 10 + (unsigned)(c - 'a'); + else + throw CArcCmdLineException("Unsupported switch postfix -stm", s); + for (unsigned k = 0; k < 4; k++) + { + const unsigned cpu = (a.Len() - 1 - i) * 4 + k; + if (v & ((unsigned)1 << k)) + aff.CpuSet(cpu); + } + } + + if (!aff.SetProcAffinity()) + { + DWORD lastError = GetLastError(); + Parse1Log += " : ERROR : "; + Parse1Log += NError::MyFormatMessage(lastError); + } + } + #endif // _WIN32 + + Parse1Log.Add_LF(); } } #endif } + + struct CCodePagePair { const char *Name; - Int32 CodePage; + UInt32 CodePage; }; static const unsigned kNumByteOnlyCodePages = 3; @@ -955,8 +1183,8 @@ static const CCodePagePair g_CodePagePairs[] = { "utf-8", CP_UTF8 }, { "win", CP_ACP }, { "dos", CP_OEMCP }, - { "utf-16le", MY__CP_UTF16 }, - { "utf-16be", MY__CP_UTF16BE } + { "utf-16le", Z7_WIN_CP_UTF16 }, + { "utf-16be", Z7_WIN_CP_UTF16BE } }; static Int32 FindCharset(const NCommandLineParser::CParser &parser, unsigned keyIndex, @@ -965,81 +1193,23 @@ static Int32 FindCharset(const NCommandLineParser::CParser &parser, unsigned key if (!parser[keyIndex].ThereIs) return defaultVal; - UString name = parser[keyIndex].PostStrings.Back(); + UString name (parser[keyIndex].PostStrings.Back()); UInt32 v; if (StringToUInt32(name, v)) if (v < ((UInt32)1 << 16)) return (Int32)v; name.MakeLower_Ascii(); - unsigned num = byteOnlyCodePages ? kNumByteOnlyCodePages : ARRAY_SIZE(g_CodePagePairs); + const unsigned num = byteOnlyCodePages ? kNumByteOnlyCodePages : Z7_ARRAY_SIZE(g_CodePagePairs); for (unsigned i = 0;; i++) { if (i == num) // to disable warnings from different compilers throw CArcCmdLineException("Unsupported charset:", name); const CCodePagePair &pair = g_CodePagePairs[i]; if (name.IsEqualTo(pair.Name)) - return pair.CodePage; + return (Int32)pair.CodePage; } } -HRESULT EnumerateDirItemsAndSort( - NWildcard::CCensor &censor, - NWildcard::ECensorPathMode censorPathMode, - const UString &addPathPrefix, - UStringVector &sortedPaths, - UStringVector &sortedFullPaths, - CDirItemsStat &st, - IDirItemsCallback *callback) -{ - FStringVector paths; - - { - CDirItems dirItems; - dirItems.Callback = callback; - { - HRESULT res = EnumerateItems(censor, censorPathMode, addPathPrefix, dirItems); - st = dirItems.Stat; - RINOK(res); - } - - FOR_VECTOR (i, dirItems.Items) - { - const CDirItem &dirItem = dirItems.Items[i]; - if (!dirItem.IsDir()) - paths.Add(dirItems.GetPhyPath(i)); - } - } - - if (paths.Size() == 0) - throw CArcCmdLineException(kCannotFindArchive); - - UStringVector fullPaths; - - unsigned i; - - for (i = 0; i < paths.Size(); i++) - { - FString fullPath; - NFile::NDir::MyGetFullPathName(paths[i], fullPath); - fullPaths.Add(fs2us(fullPath)); - } - - CUIntVector indices; - SortFileNames(fullPaths, indices); - sortedPaths.ClearAndReserve(indices.Size()); - sortedFullPaths.ClearAndReserve(indices.Size()); - - for (i = 0; i < indices.Size(); i++) - { - unsigned index = indices[i]; - sortedPaths.AddInReserved(fs2us(paths[index])); - sortedFullPaths.AddInReserved(fullPaths[index]); - if (i > 0 && CompareFileNames(sortedFullPaths[i], sortedFullPaths[i - 1]) == 0) - throw CArcCmdLineException("Duplicate archive path:", sortedFullPaths[i]); - } - - return S_OK; -} static void SetBoolPair(NCommandLineParser::CParser &parser, unsigned switchID, CBoolPair &bp) { @@ -1051,7 +1221,7 @@ static void SetBoolPair(NCommandLineParser::CParser &parser, unsigned switchID, void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options) { const UStringVector &nonSwitchStrings = parser.NonSwitchStrings; - unsigned numNonSwitchStrings = nonSwitchStrings.Size(); + const unsigned numNonSwitchStrings = nonSwitchStrings.Size(); if (numNonSwitchStrings < kMinNonSwitchWords) throw CArcCmdLineException("The command must be specified"); @@ -1060,6 +1230,27 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options) if (parser[NKey::kHash].ThereIs) options.HashMethods = parser[NKey::kHash].PostStrings; + + /* + if (parser[NKey::kHashGenFile].ThereIs) + { + const UString &s = parser[NKey::kHashGenFile].PostStrings[0]; + for (unsigned i = 0 ; i < s.Len();) + { + const wchar_t c = s[i++]; + if (!options.HashOptions.ParseFlagCharOption(c, true)) + { + if (c != '=') + throw CArcCmdLineException("Unsupported hash mode switch:", s); + options.HashOptions.HashFilePath = s.Ptr(i); + break; + } + } + } + */ + + if (parser[NKey::kHashDir].ThereIs) + options.ExtractOptions.HashDir = parser[NKey::kHashDir].PostStrings[0]; if (parser[NKey::kElimDup].ThereIs) { @@ -1082,31 +1273,51 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options) } } - NRecursedType::EEnum recursedType; + if (parser[NKey::kNameTrailReplace].ThereIs) + g_PathTrailReplaceMode = !parser[NKey::kNameTrailReplace].WithMinus; + + CNameOption nop; + if (parser[NKey::kRecursed].ThereIs) - recursedType = GetRecursedTypeFromIndex(parser[NKey::kRecursed].PostCharIndex); - else - recursedType = NRecursedType::kNonRecursed; + nop.RecursedType = GetRecursedTypeFromIndex(parser[NKey::kRecursed].PostCharIndex); - bool wildcardMatching = true; if (parser[NKey::kDisableWildcardParsing].ThereIs) - wildcardMatching = false; + nop.WildcardMatching = false; + + if (parser[NKey::kUseSlashMark].ThereIs) + { + const UString &s = parser[NKey::kUseSlashMark].PostStrings[0]; + if (s.IsEmpty()) + nop.MarkMode = NWildcard::kMark_StrictFile; + else if (s.IsEqualTo_Ascii_NoCase("-")) + nop.MarkMode = NWildcard::kMark_FileOrDir; + else if (s.IsEqualTo_Ascii_NoCase("2")) + nop.MarkMode = NWildcard::kMark_StrictFile_IfWildcard; + else + throw CArcCmdLineException("Unsupported -spm:", s); + } - g_CodePage = FindCharset(parser, NKey::kConsoleCharSet, true, -1); - Int32 codePage = FindCharset(parser, NKey::kListfileCharSet, false, CP_UTF8); + + options.ConsoleCodePage = FindCharset(parser, NKey::kConsoleCharSet, true, -1); + + UInt32 codePage = (UInt32)FindCharset(parser, NKey::kListfileCharSet, false, CP_UTF8); bool thereAreSwitchIncludes = false; - + if (parser[NKey::kInclude].ThereIs) { thereAreSwitchIncludes = true; + nop.Include = true; AddSwitchWildcardsToCensor(options.Censor, - parser[NKey::kInclude].PostStrings, true, recursedType, wildcardMatching, codePage); + parser[NKey::kInclude].PostStrings, nop, codePage); } if (parser[NKey::kExclude].ThereIs) + { + nop.Include = false; AddSwitchWildcardsToCensor(options.Censor, - parser[NKey::kExclude].PostStrings, false, recursedType, wildcardMatching, codePage); + parser[NKey::kExclude].PostStrings, nop, codePage); + } unsigned curCommandIndex = kCommandIndex + 1; bool thereIsArchiveName = !parser[NKey::kNoArName].ThereIs && @@ -1114,9 +1325,9 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options) options.Command.CommandType != NCommandType::kInfo && options.Command.CommandType != NCommandType::kHash; - bool isExtractGroupCommand = options.Command.IsFromExtractGroup(); - bool isExtractOrList = isExtractGroupCommand || options.Command.CommandType == NCommandType::kList; - bool isRename = options.Command.CommandType == NCommandType::kRename; + const bool isExtractGroupCommand = options.Command.IsFromExtractGroup(); + const bool isExtractOrList = isExtractGroupCommand || options.Command.CommandType == NCommandType::kList; + const bool isRename = options.Command.CommandType == NCommandType::kRename; if ((isExtractOrList || isRename) && options.StdInMode) thereIsArchiveName = false; @@ -1136,15 +1347,17 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options) #endif } + nop.Include = true; AddToCensorFromNonSwitchesStrings(isRename ? &options.UpdateOptions.RenamePairs : NULL, curCommandIndex, options.Censor, - nonSwitchStrings, recursedType, wildcardMatching, + nonSwitchStrings, parser.StopSwitchIndex, + nop, thereAreSwitchIncludes, codePage); options.YesToAll = parser[NKey::kYes].ThereIs; - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO options.PasswordEnabled = parser[NKey::kPassword].ThereIs; if (options.PasswordEnabled) options.Password = parser[NKey::kPassword].PostStrings[0]; @@ -1164,11 +1377,41 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options) SetBoolPair(parser, NKey::kAltStreams, options.AltStreams); SetBoolPair(parser, NKey::kHardLinks, options.HardLinks); SetBoolPair(parser, NKey::kSymLinks, options.SymLinks); + + SetBoolPair(parser, NKey::kStoreOwnerId, options.StoreOwnerId); + SetBoolPair(parser, NKey::kStoreOwnerName, options.StoreOwnerName); + + CBoolPair symLinks_AllowDangerous; + SetBoolPair(parser, NKey::kSymLinks_AllowDangerous, symLinks_AllowDangerous); + + + /* + bool supportSymLink = options.SymLinks.Val; + + if (!options.SymLinks.Def) + { + if (isExtractOrList) + supportSymLink = true; + else + supportSymLink = false; + } + + #ifdef ENV_HAVE_LSTAT + if (supportSymLink) + global_use_lstat = 1; + else + global_use_lstat = 0; + #endif + */ + if (isExtractOrList) { CExtractOptionsBase &eo = options.ExtractOptions; + eo.ExcludeDirItems = options.Censor.ExcludeDirItems; + eo.ExcludeFileItems = options.Censor.ExcludeFileItems; + { CExtractNtOptions &nt = eo.NtOptions; nt.NtSecurity = options.NtSecurity; @@ -1185,10 +1428,33 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options) if (!options.SymLinks.Def) nt.SymLinks.Val = true; + nt.SymLinks_AllowDangerous = symLinks_AllowDangerous; + nt.ReplaceColonForAltStream = parser[NKey::kReplaceColonForAltStream].ThereIs; nt.WriteToAltStreamIfColon = parser[NKey::kWriteToAltStreamIfColon].ThereIs; + + nt.ExtractOwner = options.StoreOwnerId.Val; // StoreOwnerName + + if (parser[NKey::kPreserveATime].ThereIs) + nt.PreserveATime = true; + if (parser[NKey::kShareForWrite].ThereIs) + nt.OpenShareForWrite = true; } - + + if (parser[NKey::kZoneFile].ThereIs) + { + eo.ZoneMode = NExtract::NZoneIdMode::kAll; + const UString &s = parser[NKey::kZoneFile].PostStrings[0]; + if (!s.IsEmpty()) + { + if (s == L"0") eo.ZoneMode = NExtract::NZoneIdMode::kNone; + else if (s == L"1") eo.ZoneMode = NExtract::NZoneIdMode::kAll; + else if (s == L"2") eo.ZoneMode = NExtract::NZoneIdMode::kOffice; + else + throw CArcCmdLineException("Unsupported -snz:", s); + } + } + options.Censor.AddPathsToCensor(NWildcard::k_AbsPath); options.Censor.ExtendExclude(); @@ -1198,13 +1464,28 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options) NWildcard::CCensor &arcCensor = options.arcCensor; + CNameOption nopArc; + // nopArc.RecursedType = NRecursedType::kNonRecursed; // default: we don't want recursing for archives, if -r specified + // is it OK, external switches can disable WildcardMatching and MarcMode for arc. + nopArc.WildcardMatching = nop.WildcardMatching; + nopArc.MarkMode = nop.MarkMode; + if (parser[NKey::kArInclude].ThereIs) - AddSwitchWildcardsToCensor(arcCensor, parser[NKey::kArInclude].PostStrings, true, NRecursedType::kNonRecursed, wildcardMatching, codePage); + { + nopArc.Include = true; + AddSwitchWildcardsToCensor(arcCensor, parser[NKey::kArInclude].PostStrings, nopArc, codePage); + } if (parser[NKey::kArExclude].ThereIs) - AddSwitchWildcardsToCensor(arcCensor, parser[NKey::kArExclude].PostStrings, false, NRecursedType::kNonRecursed, wildcardMatching, codePage); + { + nopArc.Include = false; + AddSwitchWildcardsToCensor(arcCensor, parser[NKey::kArExclude].PostStrings, nopArc, codePage); + } if (thereIsArchiveName) - AddNameToCensor(arcCensor, options.ArchiveName, true, NRecursedType::kNonRecursed, wildcardMatching); + { + nopArc.Include = true; + AddNameToCensor(arcCensor, nopArc, options.ArchiveName); + } arcCensor.AddPathsToCensor(NWildcard::k_RelatPath); @@ -1242,6 +1523,9 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options) if (parser[NKey::kOutputDir].ThereIs) { eo.OutputDir = us2fs(parser[NKey::kOutputDir].PostStrings[0]); + #ifdef _WIN32 + NFile::NName::NormalizeDirSeparators(eo.OutputDir); + #endif NFile::NName::NormalizeDirPathPrefix(eo.OutputDir); } @@ -1281,8 +1565,12 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options) updateOptions.MethodMode.Properties = options.Properties; + if (parser[NKey::kPreserveATime].ThereIs) + updateOptions.PreserveATime = true; if (parser[NKey::kShareForWrite].ThereIs) updateOptions.OpenShareForWrite = true; + if (parser[NKey::kStopAfterOpenError].ThereIs) + updateOptions.StopAfterOpenError = true; updateOptions.PathMode = censorPathMode; @@ -1290,6 +1578,9 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options) updateOptions.NtSecurity = options.NtSecurity; updateOptions.HardLinks = options.HardLinks; updateOptions.SymLinks = options.SymLinks; + + updateOptions.StoreOwnerId = options.StoreOwnerId; + updateOptions.StoreOwnerName = options.StoreOwnerName; updateOptions.EMailMode = parser[NKey::kEmail].ThereIs; if (updateOptions.EMailMode) @@ -1333,11 +1624,13 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options) else if (options.Command.CommandType == NCommandType::kBenchmark) { options.NumIterations = 1; + options.NumIterations_Defined = false; if (curCommandIndex < numNonSwitchStrings) { if (!StringToUInt32(nonSwitchStrings[curCommandIndex], options.NumIterations)) - throw CArcCmdLineException("Incorrect Number of benmchmark iterations", nonSwitchStrings[curCommandIndex]); + throw CArcCmdLineException("Incorrect number of benchmark iterations", nonSwitchStrings[curCommandIndex]); curCommandIndex++; + options.NumIterations_Defined = true; } } else if (options.Command.CommandType == NCommandType::kHash) @@ -1348,10 +1641,14 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options) CHashOptions &hashOptions = options.HashOptions; hashOptions.PathMode = censorPathMode; hashOptions.Methods = options.HashMethods; + // hashOptions.HashFilePath = options.HashFilePath; + if (parser[NKey::kPreserveATime].ThereIs) + hashOptions.PreserveATime = true; if (parser[NKey::kShareForWrite].ThereIs) hashOptions.OpenShareForWrite = true; hashOptions.StdInMode = options.StdInMode; hashOptions.AltStreamsMode = options.AltStreams.Val; + hashOptions.SymLinks = options.SymLinks; } else if (options.Command.CommandType == NCommandType::kInfo) { @@ -1359,3 +1656,45 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options) else throw 20150919; } + + + +#ifndef _WIN32 + +static AString g_ModuleDirPrefix; + +void Set_ModuleDirPrefix_From_ProgArg0(const char *s); +void Set_ModuleDirPrefix_From_ProgArg0(const char *s) +{ + AString a (s); + int sep = a.ReverseFind_PathSepar(); + a.DeleteFrom((unsigned)(sep + 1)); + g_ModuleDirPrefix = a; +} + +namespace NWindows { +namespace NDLL { + +FString GetModuleDirPrefix(); +FString GetModuleDirPrefix() +{ + FString s; + + s = fas2fs(g_ModuleDirPrefix); + if (s.IsEmpty()) + s = FTEXT(".") FSTRING_PATH_SEPARATOR; + return s; + /* + setenv("_7ZIP_HOME_DIR", "/test/", 0); + const char *home = getenv("_7ZIP_HOME_DIR"); + if (home) + s = home; + else + s = FTEXT(".") FSTRING_PATH_SEPARATOR; + return s; + */ +} + +}} + +#endif // ! _WIN32 diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveCommandLine.h b/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveCommandLine.h index a345505cb84..9e375b55aba 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveCommandLine.h +++ b/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveCommandLine.h @@ -1,19 +1,18 @@ // ArchiveCommandLine.h -#ifndef __ARCHIVE_COMMAND_LINE_H -#define __ARCHIVE_COMMAND_LINE_H +#ifndef ZIP7_INC_ARCHIVE_COMMAND_LINE_H +#define ZIP7_INC_ARCHIVE_COMMAND_LINE_H #include "../../../Common/CommandLineParser.h" #include "../../../Common/Wildcard.h" +#include "EnumDirItems.h" + #include "Extract.h" #include "HashCalc.h" #include "Update.h" -struct CArcCmdLineException: public UString -{ - CArcCmdLineException(const char *a, const wchar_t *u = NULL); -}; +typedef CMessagePathException CArcCmdLineException; namespace NCommandType { enum EEnum { @@ -51,8 +50,8 @@ struct CArcCmdLineOptions { bool HelpMode; - bool LargePages; - bool CaseSensitiveChange; + // bool LargePages; + bool CaseSensitive_Change; bool CaseSensitive; bool IsInTerminal; @@ -64,22 +63,35 @@ struct CArcCmdLineOptions bool YesToAll; bool ShowDialog; + bool TechMode; + bool ShowTime; + + CBoolPair NtSecurity; + CBoolPair AltStreams; + CBoolPair HardLinks; + CBoolPair SymLinks; + + CBoolPair StoreOwnerId; + CBoolPair StoreOwnerName; + + AString ListFields; + + int ConsoleCodePage; + NWildcard::CCensor Censor; CArcCommand Command; UString ArchiveName; - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO bool PasswordEnabled; UString Password; #endif - bool TechMode; - bool ShowTime; - UStringVector HashMethods; + // UString HashFilePath; - bool AppendName; + // bool AppendName; // UStringVector ArchivePathsSorted; // UStringVector ArchivePathsFullSorted; NWildcard::CCensor arcCensor; @@ -89,11 +101,6 @@ struct CArcCmdLineOptions CExtractOptionsBase ExtractOptions; - CBoolPair NtSecurity; - CBoolPair AltStreams; - CBoolPair HardLinks; - CBoolPair SymLinks; - CUpdateOptions UpdateOptions; CHashOptions HashOptions; UString ArcType; @@ -108,40 +115,46 @@ struct CArcCmdLineOptions // Benchmark UInt32 NumIterations; + bool NumIterations_Defined; CArcCmdLineOptions(): - LargePages(false), - CaseSensitiveChange(false), + HelpMode(false), + // LargePages(false), + CaseSensitive_Change(false), CaseSensitive(false), + IsInTerminal(false), + IsStdOutTerminal(false), + IsStdErrTerminal(false), + StdInMode(false), StdOutMode(false), + EnableHeaders(false), + + YesToAll(false), + ShowDialog(false), + TechMode(false), + ShowTime(false), + + ConsoleCodePage(-1), + Number_for_Out(k_OutStream_stdout), Number_for_Errors(k_OutStream_stderr), Number_for_Percents(k_OutStream_stdout), LogLevel(0) { - }; + } }; class CArcCmdLineParser { NCommandLineParser::CParser parser; public: - CArcCmdLineParser(); + UString Parse1Log; void Parse1(const UStringVector &commandStrings, CArcCmdLineOptions &options); void Parse2(CArcCmdLineOptions &options); }; -HRESULT EnumerateDirItemsAndSort( - NWildcard::CCensor &censor, - NWildcard::ECensorPathMode pathMode, - const UString &addPathPrefix, - UStringVector &sortedPaths, - UStringVector &sortedFullPaths, - CDirItemsStat &st, - IDirItemsCallback *callback); - #endif diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp index bc116c93d66..4b0cbedad31 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp @@ -5,11 +5,17 @@ #undef sprintf #undef printf +// #include <stdio.h> +// #include "../../../../C/CpuTicks.h" + #include "../../../../C/Alloc.h" +#include "../../../../C/CpuArch.h" + #include "../../../Common/ComTry.h" #include "../../../Common/IntToString.h" #include "../../../Common/StringConvert.h" +#include "../../../Common/UTFConvert.h" #include "../../../Common/Wildcard.h" #include "../../../Windows/ErrorMsg.h" @@ -19,13 +25,13 @@ #include "../../../Windows/PropVariant.h" #include "../../../Windows/PropVariantConv.h" -#if defined(_WIN32) && !defined(UNDER_CE) && !defined(_SFX) -#define _USE_SECURITY_CODE +#if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX) +#define Z7_USE_SECURITY_CODE #include "../../../Windows/SecurityUtils.h" #endif #include "../../Common/FilePathAutoRename.h" -// #include "../../Common/StreamUtils.h" +#include "../../Common/StreamUtils.h" #include "../Common/ExtractingFilePath.h" #include "../Common/PropIDUtils.h" @@ -36,15 +42,21 @@ using namespace NWindows; using namespace NFile; using namespace NDir; -static const char *kCantAutoRename = "Can not create file with auto name"; -static const char *kCantRenameFile = "Can not rename existing file"; -static const char *kCantDeleteOutputFile = "Can not delete output file"; -static const char *kCantDeleteOutputDir = "Can not delete output folder"; - +static const char * const kCantAutoRename = "Cannot create file with auto name"; +static const char * const kCantRenameFile = "Cannot rename existing file"; +static const char * const kCantDeleteOutputFile = "Cannot delete output file"; +static const char * const kCantDeleteOutputDir = "Cannot delete output folder"; +static const char * const kCantOpenOutFile = "Cannot open output file"; +static const char * const kCantOpenInFile = "Cannot open input file"; +static const char * const kCantSetFileLen = "Cannot set length for output file"; +#ifdef SUPPORT_LINKS +static const char * const kCantCreateHardLink = "Cannot create hard link"; +static const char * const kCantCreateSymLink = "Cannot create symbolic link"; +#endif -#ifndef _SFX +#ifndef Z7_SFX -STDMETHODIMP COutStreamWithHash::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(COutStreamWithHash::Write(const void *data, UInt32 size, UInt32 *processedSize)) { HRESULT result = S_OK; if (_stream) @@ -57,9 +69,11 @@ STDMETHODIMP COutStreamWithHash::Write(const void *data, UInt32 size, UInt32 *pr return result; } -#endif +#endif // Z7_SFX -#ifdef _USE_SECURITY_CODE + +#ifdef Z7_USE_SECURITY_CODE +bool InitLocalPrivileges(); bool InitLocalPrivileges() { NSecurity::CAccessToken token; @@ -78,8 +92,86 @@ bool InitLocalPrivileges() return false; return (GetLastError() == ERROR_SUCCESS); } +#endif // Z7_USE_SECURITY_CODE + + + +#if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX) + +static const char * const kOfficeExtensions = + " doc dot wbk" + " docx docm dotx dotm docb wll wwl" + " xls xlt xlm" + " xlsx xlsm xltx xltm xlsb xla xlam" + " ppt pot pps ppa ppam" + " pptx pptm potx potm ppam ppsx ppsm sldx sldm" + " "; + +static bool FindExt2(const char *p, const UString &name) +{ + const int pathPos = name.ReverseFind_PathSepar(); + const int dotPos = name.ReverseFind_Dot(); + if (dotPos < 0 + || dotPos < pathPos + || dotPos == (int)name.Len() - 1) + return false; + + AString s; + for (unsigned pos = (unsigned)(dotPos + 1);; pos++) + { + const wchar_t c = name[pos]; + if (c <= 0) + break; + if (c >= 0x80) + return false; + s += (char)MyCharLower_Ascii((char)c); + } + for (unsigned i = 0; p[i] != 0;) + { + unsigned j; + for (j = i; p[j] != ' '; j++); + if (s.Len() == j - i && memcmp(p + i, (const char *)s, s.Len()) == 0) + return true; + i = j + 1; + } + return false; +} + + +static const FChar * const k_ZoneId_StreamName = FTEXT(":Zone.Identifier"); + +void ReadZoneFile_Of_BaseFile(CFSTR fileName2, CByteBuffer &buf) +{ + FString fileName (fileName2); + fileName += k_ZoneId_StreamName; + + buf.Free(); + NIO::CInFile file; + if (!file.Open(fileName)) + return; + UInt64 fileSize; + if (!file.GetLength(fileSize)) + return; + if (fileSize == 0 || fileSize >= ((UInt32)1 << 16)) + return; + buf.Alloc((size_t)fileSize); + size_t processed; + if (file.ReadFull(buf, (size_t)fileSize, processed) && processed == fileSize) + return; + buf.Free(); +} + +static bool WriteZoneFile(CFSTR fileName, const CByteBuffer &buf) +{ + NIO::COutFile file; + if (!file.Create(fileName, true)) + return false; + return file.WriteFull(buf, buf.Size()); +} + #endif + #ifdef SUPPORT_LINKS int CHardLinkNode::Compare(const CHardLinkNode &a) const @@ -96,13 +188,13 @@ static HRESULT Archive_Get_HardLinkNode(IInArchive *archive, UInt32 index, CHard defined = false; { NCOM::CPropVariant prop; - RINOK(archive->GetProperty(index, kpidINode, &prop)); + RINOK(archive->GetProperty(index, kpidINode, &prop)) if (!ConvertPropVariantToUInt64(prop, h.INode)) return S_OK; } { NCOM::CPropVariant prop; - RINOK(archive->GetProperty(index, kpidStreamId, &prop)); + RINOK(archive->GetProperty(index, kpidStreamId, &prop)) ConvertPropVariantToUInt64(prop, h.StreamId); } defined = true; @@ -126,22 +218,27 @@ HRESULT CArchiveExtractCallback::PrepareHardLinks(const CRecordVector<UInt32> *r numItems = realIndices->Size(); else { - RINOK(archive->GetNumberOfItems(&numItems)); + RINOK(archive->GetNumberOfItems(&numItems)) } for (UInt32 i = 0; i < numItems; i++) { CHardLinkNode h; bool defined; - UInt32 realIndex = realIndices ? (*realIndices)[i] : i; + const UInt32 realIndex = realIndices ? (*realIndices)[i] : i; - RINOK(Archive_Get_HardLinkNode(archive, realIndex, h, defined)); + RINOK(Archive_Get_HardLinkNode(archive, realIndex, h, defined)) if (defined) { bool isAltStream = false; - RINOK(Archive_IsItem_AltStream(archive, realIndex, isAltStream)); + RINOK(Archive_IsItem_AltStream(archive, realIndex, isAltStream)) if (!isAltStream) - hardIDs.Add(h); + { + bool isDir = false; + RINOK(Archive_IsItem_Dir(archive, realIndex, isDir)) + if (!isDir) + hardIDs.Add(h); + } } } } @@ -149,7 +246,7 @@ HRESULT CArchiveExtractCallback::PrepareHardLinks(const CRecordVector<UInt32> *r hardIDs.Sort2(); { - // wee keep only items that have 2 or more items + // we keep only items that have 2 or more items unsigned k = 0; unsigned numSame = 1; for (unsigned i = 1; i < hardIDs.Size(); i++) @@ -170,22 +267,32 @@ HRESULT CArchiveExtractCallback::PrepareHardLinks(const CRecordVector<UInt32> *r return S_OK; } -#endif +#endif // SUPPORT_LINKS + CArchiveExtractCallback::CArchiveExtractCallback(): - WriteCTime(true), - WriteATime(true), - WriteMTime(true), + _arc(NULL), + Write_CTime(true), + Write_ATime(true), + Write_MTime(true), _multiArchives(false) { LocalProgressSpec = new CLocalProgress(); _localProgress = LocalProgressSpec; - #ifdef _USE_SECURITY_CODE + #ifdef Z7_USE_SECURITY_CODE _saclEnabled = InitLocalPrivileges(); #endif } + +void CArchiveExtractCallback::InitBeforeNewArchive() +{ + #if defined(_WIN32) && !defined(UNDER_CE) + ZoneBuf.Free(); + #endif +} + void CArchiveExtractCallback::Init( const CExtractNtOptions &ntOptions, const NWildcard::CCensorNode *wildcardCensor, @@ -196,8 +303,9 @@ void CArchiveExtractCallback::Init( const UStringVector &removePathParts, bool removePartsForAltStreams, UInt64 packSize) { - _extractedFolderPaths.Clear(); - _extractedFolderIndices.Clear(); + ClearExtractedDirsInfo(); + _outFileStream.Release(); + _bufPtrSeqOutStream.Release(); #ifdef SUPPORT_LINKS _hardLinks.Clear(); @@ -221,13 +329,21 @@ void CArchiveExtractCallback::Init( _progressTotal_Defined = true; _extractCallback2 = extractCallback2; + + /* _compressProgress.Release(); _extractCallback2.QueryInterface(IID_ICompressProgressInfo, &_compressProgress); - _extractCallback2.QueryInterface(IID_IArchiveExtractCallbackMessage, &_callbackMessage); + + _callbackMessage.Release(); + _extractCallback2.QueryInterface(IID_IArchiveExtractCallbackMessage2, &_callbackMessage); + */ + + _folderArchiveExtractCallback2.Release(); _extractCallback2.QueryInterface(IID_IFolderArchiveExtractCallback2, &_folderArchiveExtractCallback2); - #ifndef _SFX + #ifndef Z7_SFX + ExtractToStreamCallback.Release(); _extractCallback2.QueryInterface(IID_IFolderExtractToStreamCallback, &ExtractToStreamCallback); if (ExtractToStreamCallback) { @@ -246,7 +362,7 @@ void CArchiveExtractCallback::Init( _removePathParts = removePathParts; _removePartsForAltStreams = removePartsForAltStreams; - #ifndef _SFX + #ifndef Z7_SFX _baseParentFolder = (UInt32)(Int32)-1; _use_baseParentFolder_mode = false; #endif @@ -264,7 +380,8 @@ void CArchiveExtractCallback::Init( } } -STDMETHODIMP CArchiveExtractCallback::SetTotal(UInt64 size) + +Z7_COM7F_IMF(CArchiveExtractCallback::SetTotal(UInt64 size)) { COM_TRY_BEGIN _progressTotal = size; @@ -275,6 +392,7 @@ STDMETHODIMP CArchiveExtractCallback::SetTotal(UInt64 size) COM_TRY_END } + static void NormalizeVals(UInt64 &v1, UInt64 &v2) { const UInt64 kMax = (UInt64)1 << 31; @@ -285,6 +403,7 @@ static void NormalizeVals(UInt64 &v1, UInt64 &v2) } } + static UInt64 MyMultDiv64(UInt64 unpCur, UInt64 unpTotal, UInt64 packTotal) { NormalizeVals(packTotal, unpTotal); @@ -294,7 +413,8 @@ static UInt64 MyMultDiv64(UInt64 unpCur, UInt64 unpTotal, UInt64 packTotal) return unpCur * packTotal / unpTotal; } -STDMETHODIMP CArchiveExtractCallback::SetCompleted(const UInt64 *completeValue) + +Z7_COM7F_IMF(CArchiveExtractCallback::SetCompleted(const UInt64 *completeValue)) { COM_TRY_BEGIN @@ -314,15 +434,19 @@ STDMETHODIMP CArchiveExtractCallback::SetCompleted(const UInt64 *completeValue) COM_TRY_END } -STDMETHODIMP CArchiveExtractCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) + +Z7_COM7F_IMF(CArchiveExtractCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)) { COM_TRY_BEGIN return _localProgress->SetRatioInfo(inSize, outSize); COM_TRY_END } + void CArchiveExtractCallback::CreateComplexDirectory(const UStringVector &dirPathParts, FString &fullPath) { + // we use (_item.IsDir) in this function + bool isAbsPath = false; if (!dirPathParts.IsEmpty()) @@ -350,45 +474,72 @@ void CArchiveExtractCallback::CreateComplexDirectory(const UStringVector &dirPat fullPath.Add_PathSepar(); const UString &s = dirPathParts[i]; fullPath += us2fs(s); + + const bool isFinalDir = (i == dirPathParts.Size() - 1 && _item.IsDir); + + if (fullPath.IsEmpty()) + { + if (isFinalDir) + _itemFailure = true; + continue; + } + #if defined(_WIN32) && !defined(UNDER_CE) if (_pathMode == NExtract::NPathMode::kAbsPaths) if (i == 0 && s.Len() == 2 && NName::IsDrivePath2(s)) + { + if (isFinalDir) + { + // we don't want to call SetAttrib() for root drive path + _itemFailure = true; + } continue; + } #endif + + // bool res = CreateDir(fullPath); + // if (!res) + if (isFinalDir) + { + if (!NFile::NFind::DoesDirExist(fullPath)) + { + _itemFailure = true; + SendMessageError("Cannot create folder", fullPath); + // SendMessageError_with_LastError() + } + } } } -HRESULT CArchiveExtractCallback::GetTime(int index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined) + +HRESULT CArchiveExtractCallback::GetTime(UInt32 index, PROPID propID, CArcTime &ft) { - filetimeIsDefined = false; + ft.Clear(); NCOM::CPropVariant prop; - RINOK(_arc->Archive->GetProperty(index, propID, &prop)); + RINOK(_arc->Archive->GetProperty(index, propID, &prop)) if (prop.vt == VT_FILETIME) - { - filetime = prop.filetime; - filetimeIsDefined = (filetime.dwHighDateTime != 0 || filetime.dwLowDateTime != 0); - } + ft.Set_From_Prop(prop); else if (prop.vt != VT_EMPTY) return E_FAIL; return S_OK; } + HRESULT CArchiveExtractCallback::GetUnpackSize() { - return _arc->GetItemSize(_index, _curSize, _curSizeDefined); + return _arc->GetItem_Size(_index, _curSize, _curSize_Defined); } static void AddPathToMessage(UString &s, const FString &path) { - s.AddAscii(" : "); + s += " : "; s += fs2us(path); } HRESULT CArchiveExtractCallback::SendMessageError(const char *message, const FString &path) { - UString s; - s.AddAscii(message); + UString s (message); AddPathToMessage(s, path); return _extractCallback2->MessageError(s); } @@ -396,29 +547,33 @@ HRESULT CArchiveExtractCallback::SendMessageError(const char *message, const FSt HRESULT CArchiveExtractCallback::SendMessageError_with_LastError(const char *message, const FString &path) { DWORD errorCode = GetLastError(); - UString s; - s.AddAscii(message); - if (errorCode != 0) + if (errorCode == 0) + errorCode = (DWORD)E_FAIL; + UString s (message); { - s.AddAscii(" : "); + s += " : "; s += NError::MyFormatMessage(errorCode); } AddPathToMessage(s, path); return _extractCallback2->MessageError(s); } -HRESULT CArchiveExtractCallback::SendMessageError2(const char *message, const FString &path1, const FString &path2) +HRESULT CArchiveExtractCallback::SendMessageError2(HRESULT errorCode, const char *message, const FString &path1, const FString &path2) { - UString s; - s.AddAscii(message); + UString s (message); + if (errorCode != 0) + { + s += " : "; + s += NError::MyFormatMessage(errorCode); + } AddPathToMessage(s, path1); AddPathToMessage(s, path2); return _extractCallback2->MessageError(s); } -#ifndef _SFX +#ifndef Z7_SFX -STDMETHODIMP CGetProp::GetProp(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CGetProp::GetProp(PROPID propID, PROPVARIANT *value)) { /* if (propID == kpidName) @@ -433,35 +588,45 @@ STDMETHODIMP CGetProp::GetProp(PROPID propID, PROPVARIANT *value) return Arc->Archive->GetProperty(IndexInArc, propID, value); } -#endif +#endif // Z7_SFX #ifdef SUPPORT_LINKS static UString GetDirPrefixOf(const UString &src) { - UString s = src; + UString s (src); if (!s.IsEmpty()) { if (IsPathSepar(s.Back())) s.DeleteBack(); int pos = s.ReverseFind_PathSepar(); - s.DeleteFrom(pos + 1); + s.DeleteFrom((unsigned)(pos + 1)); } return s; } -#endif +#endif // SUPPORT_LINKS +struct CLinkLevelsInfo +{ + bool IsAbsolute; + int LowLevel; + int FinalLevel; -bool IsSafePath(const UString &path) + void Parse(const UString &path); +}; + +void CLinkLevelsInfo::Parse(const UString &path) { - if (NName::IsAbsolutePath(path)) - return false; + IsAbsolute = NName::IsAbsolutePath(path); + + LowLevel = 0; + FinalLevel = 0; UStringVector parts; SplitPathToParts(path, parts); - unsigned level = 0; + int level = 0; FOR_VECTOR (i, parts) { @@ -469,29 +634,42 @@ bool IsSafePath(const UString &path) if (s.IsEmpty()) { if (i == 0) - return false; + IsAbsolute = true; continue; } if (s == L".") continue; if (s == L"..") { - if (level == 0) - return false; level--; + if (LowLevel > level) + LowLevel = level; } else level++; } - return level > 0; + FinalLevel = level; +} + + +bool IsSafePath(const UString &path); +bool IsSafePath(const UString &path) +{ + CLinkLevelsInfo levelsInfo; + levelsInfo.Parse(path); + return !levelsInfo.IsAbsolute + && levelsInfo.LowLevel >= 0 + && levelsInfo.FinalLevel > 0; } +bool CensorNode_CheckPath2(const NWildcard::CCensorNode &node, const CReadArcItem &item, bool &include); bool CensorNode_CheckPath2(const NWildcard::CCensorNode &node, const CReadArcItem &item, bool &include) { bool found = false; - + + // CheckPathVect() doesn't check path to Parent nodes if (node.CheckPathVect(item.PathParts, !item.MainIsDir, include)) { if (!include) @@ -514,7 +692,7 @@ bool CensorNode_CheckPath2(const NWildcard::CCensorNode &node, const CReadArcIte if (pathParts2.IsEmpty()) pathParts2.AddNew(); UString &back = pathParts2.Back(); - back += L':'; + back += ':'; back += item.AltStreamName; bool include2; @@ -526,11 +704,12 @@ bool CensorNode_CheckPath2(const NWildcard::CCensorNode &node, const CReadArcIte return true; } - #endif + #endif // SUPPORT_ALT_STREAMS return found; } + bool CensorNode_CheckPath(const NWildcard::CCensorNode &node, const CReadArcItem &item) { bool include; @@ -539,9 +718,10 @@ bool CensorNode_CheckPath(const NWildcard::CCensorNode &node, const CReadArcItem return false; } + static FString MakePath_from_2_Parts(const FString &prefix, const FString &path) { - FString s = prefix; + FString s (prefix); #if defined(_WIN32) && !defined(UNDER_CE) if (!path.IsEmpty() && path[0] == ':' && !prefix.IsEmpty() && IsPathSepar(prefix.Back())) { @@ -554,9 +734,10 @@ static FString MakePath_from_2_Parts(const FString &prefix, const FString &path) } -/* + #ifdef SUPPORT_LINKS +/* struct CTempMidBuffer { void *Buf; @@ -575,15 +756,15 @@ HRESULT CArchiveExtractCallback::MyCopyFile(ISequentialOutStream *outStream) NIO::CInFile inFile; NIO::COutFile outFile; - if (!inFile.Open(_CopyFile_Path)) - return SendMessageError_with_LastError("Open error", _CopyFile_Path); + if (!inFile.Open(_copyFile_Path)) + return SendMessageError_with_LastError("Open error", _copyFile_Path); for (;;) { UInt32 num; if (!inFile.Read(buf.Buf, kBufSize, num)) - return SendMessageError_with_LastError("Read error", _CopyFile_Path); + return SendMessageError_with_LastError("Read error", _copyFile_Path); if (num == 0) return S_OK; @@ -592,88 +773,24 @@ HRESULT CArchiveExtractCallback::MyCopyFile(ISequentialOutStream *outStream) RINOK(WriteStream(outStream, buf.Buf, num)); } } - -#endif */ -STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode) -{ - COM_TRY_BEGIN - - *outStream = NULL; - - #ifndef _SFX - if (_hashStream) - _hashStreamSpec->ReleaseStream(); - _hashStreamWasUsed = false; - #endif - - _outFileStream.Release(); - - _encrypted = false; - _position = 0; - _isSplit = false; - - _curSize = 0; - _curSizeDefined = false; - _index = index; - - _diskFilePath.Empty(); - - // _fi.Clear(); - - #ifdef SUPPORT_LINKS - // _CopyFile_Path.Empty(); - linkPath.Empty(); - #endif +HRESULT CArchiveExtractCallback::ReadLink() +{ IInArchive *archive = _arc->Archive; - - #ifndef _SFX - _item._use_baseParentFolder_mode = _use_baseParentFolder_mode; - if (_use_baseParentFolder_mode) - { - _item._baseParentFolder = _baseParentFolder; - if (_pathMode == NExtract::NPathMode::kFullPaths || - _pathMode == NExtract::NPathMode::kAbsPaths) - _item._baseParentFolder = -1; - } - #endif - - #ifdef SUPPORT_ALT_STREAMS - _item.WriteToAltStreamIfColon = _ntOptions.WriteToAltStreamIfColon; - #endif - - RINOK(_arc->GetItem(index, _item)); + const UInt32 index = _index; + _link.Clear(); { NCOM::CPropVariant prop; - RINOK(archive->GetProperty(index, kpidPosition, &prop)); - if (prop.vt != VT_EMPTY) - { - if (prop.vt != VT_UI8) - return E_FAIL; - _position = prop.uhVal.QuadPart; - _isSplit = true; - } - } - - #ifdef SUPPORT_LINKS - - // bool isCopyLink = false; - bool isHardLink = false; - bool isJunction = false; - bool isRelative = false; - - { - NCOM::CPropVariant prop; - RINOK(archive->GetProperty(index, kpidHardLink, &prop)); + RINOK(archive->GetProperty(index, kpidHardLink, &prop)) if (prop.vt == VT_BSTR) { - isHardLink = true; - // isCopyLink = false; - isRelative = false; // RAR5, TAR: hard links are from root folder of archive - linkPath.SetFromBstr(prop.bstrVal); + _link.isHardLink = true; + // _link.isCopyLink = false; + _link.isRelative = false; // RAR5, TAR: hard links are from root folder of archive + _link.linkPath.SetFromBstr(prop.bstrVal); } else if (prop.vt != VT_EMPTY) return E_FAIL; @@ -685,10 +802,10 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre RINOK(archive->GetProperty(index, kpidCopyLink, &prop)); if (prop.vt == VT_BSTR) { - isHardLink = false; - isCopyLink = true; - isRelative = false; // RAR5: copy links are from root folder of archive - linkPath.SetFromBstr(prop.bstrVal); + _link.isHardLink = false; + _link.isCopyLink = true; + _link.isRelative = false; // RAR5: copy links are from root folder of archive + _link.linkPath.SetFromBstr(prop.bstrVal); } else if (prop.vt != VT_EMPTY) return E_FAIL; @@ -697,22 +814,22 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre { NCOM::CPropVariant prop; - RINOK(archive->GetProperty(index, kpidSymLink, &prop)); + RINOK(archive->GetProperty(index, kpidSymLink, &prop)) if (prop.vt == VT_BSTR) { - isHardLink = false; - // isCopyLink = false; - isRelative = true; // RAR5, TAR: symbolic links can be relative - linkPath.SetFromBstr(prop.bstrVal); + _link.isHardLink = false; + // _link.isCopyLink = false; + _link.isRelative = true; // RAR5, TAR: symbolic links can be relative + _link.linkPath.SetFromBstr(prop.bstrVal); } else if (prop.vt != VT_EMPTY) return E_FAIL; } + NtReparse_Data = NULL; + NtReparse_Size = 0; - bool isOkReparse = false; - - if (linkPath.IsEmpty() && _arc->GetRawProps) + if (_link.linkPath.IsEmpty() && _arc->GetRawProps) { const void *data; UInt32 dataSize; @@ -720,55 +837,79 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre _arc->GetRawProps->GetRawProp(_index, kpidNtReparse, &data, &dataSize, &propType); + // if (dataSize == 1234567) // for debug: unpacking without reparse if (dataSize != 0) { if (propType != NPropDataType::kRaw) return E_FAIL; - UString s; + + // 21.06: we need kpidNtReparse in linux for wim archives created in Windows + // #ifdef _WIN32 + + NtReparse_Data = data; + NtReparse_Size = dataSize; + CReparseAttr reparse; - isOkReparse = reparse.Parse((const Byte *)data, dataSize); + bool isOkReparse = reparse.Parse((const Byte *)data, dataSize); if (isOkReparse) { - isHardLink = false; - // isCopyLink = false; - linkPath = reparse.GetPath(); - isJunction = reparse.IsMountPoint(); - isRelative = reparse.IsRelative(); + _link.isHardLink = false; + // _link.isCopyLink = false; + _link.linkPath = reparse.GetPath(); + _link.isJunction = reparse.IsMountPoint(); + + if (reparse.IsSymLink_WSL()) + { + _link.isWSL = true; + _link.isRelative = reparse.IsRelative_WSL(); + } + else + _link.isRelative = reparse.IsRelative_Win(); + + // const AString s = GetAnsiString(_link.linkPath); + // printf("\n_link.linkPath: %s\n", s.Ptr()); + #ifndef _WIN32 - linkPath.Replace(L'\\', WCHAR_PATH_SEPARATOR); + _link.linkPath.Replace(L'\\', WCHAR_PATH_SEPARATOR); #endif } + // #endif } } - if (!linkPath.IsEmpty()) + if (_link.linkPath.IsEmpty()) + return S_OK; + { #ifdef _WIN32 - linkPath.Replace(L'/', WCHAR_PATH_SEPARATOR); + _link.linkPath.Replace(L'/', WCHAR_PATH_SEPARATOR); #endif // rar5 uses "\??\" prefix for absolute links - if (linkPath.IsPrefixedBy(WSTRING_PATH_SEPARATOR L"??" WSTRING_PATH_SEPARATOR)) + if (_link.linkPath.IsPrefixedBy(WSTRING_PATH_SEPARATOR L"??" WSTRING_PATH_SEPARATOR)) { - isRelative = false; - linkPath.DeleteFrontal(4); + _link.isRelative = false; + _link.linkPath.DeleteFrontal(4); } for (;;) // while (NName::IsAbsolutePath(linkPath)) { - unsigned n = NName::GetRootPrefixSize(linkPath); + unsigned n = NName::GetRootPrefixSize(_link.linkPath); if (n == 0) break; - isRelative = false; - linkPath.DeleteFrontal(n); + _link.isRelative = false; + _link.linkPath.DeleteFrontal(n); } } - if (!linkPath.IsEmpty() && !isRelative && _removePathParts.Size() != 0) + if (_link.linkPath.IsEmpty()) + return S_OK; + + if (!_link.isRelative && _removePathParts.Size() != 0) { UStringVector pathParts; - SplitPathToParts(linkPath, pathParts); + SplitPathToParts(_link.linkPath, pathParts); bool badPrefix = false; FOR_VECTOR (i, _removePathParts) { @@ -780,23 +921,726 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre } if (!badPrefix) pathParts.DeleteFrontal(_removePathParts.Size()); - linkPath = MakePathFromParts(pathParts); + _link.linkPath = MakePathFromParts(pathParts); + } + + /* + if (!_link.linkPath.IsEmpty()) + { + printf("\n_link %s to -> %s\n", GetOemString(_item.Path).Ptr(), GetOemString(_link.linkPath).Ptr()); + } + */ + + return S_OK; +} + +#endif // SUPPORT_LINKS + + +#ifndef _WIN32 + +static HRESULT GetOwner(IInArchive *archive, + UInt32 index, UInt32 pidName, UInt32 pidId, COwnerInfo &res) +{ + { + NWindows::NCOM::CPropVariant prop; + RINOK(archive->GetProperty(index, pidId, &prop)) + if (prop.vt == VT_UI4) + { + res.Id_Defined = true; + res.Id = prop.ulVal; // for debug + // res.Id++; // for debug + // if (pidId == kpidGroupId) res.Id += 7; // for debug + // res.Id = 0; // for debug + } + else if (prop.vt != VT_EMPTY) + return E_INVALIDARG; + } + { + NWindows::NCOM::CPropVariant prop; + RINOK(archive->GetProperty(index, pidName, &prop)) + if (prop.vt == VT_BSTR) + { + const UString s = prop.bstrVal; + ConvertUnicodeToUTF8(s, res.Name); + } + else if (prop.vt == VT_UI4) + { + res.Id_Defined = true; + res.Id = prop.ulVal; + } + else if (prop.vt != VT_EMPTY) + return E_INVALIDARG; } + return S_OK; +} +#endif + + +HRESULT CArchiveExtractCallback::Read_fi_Props() +{ + IInArchive *archive = _arc->Archive; + const UInt32 index = _index; + + _fi.Attrib_Defined = false; + + #ifndef _WIN32 + _fi.Owner.Clear(); + _fi.Group.Clear(); + #endif + + { + NCOM::CPropVariant prop; + RINOK(archive->GetProperty(index, kpidPosixAttrib, &prop)) + if (prop.vt == VT_UI4) + { + _fi.SetFromPosixAttrib(prop.ulVal); + } + else if (prop.vt != VT_EMPTY) + return E_FAIL; + } + + { + NCOM::CPropVariant prop; + RINOK(archive->GetProperty(index, kpidAttrib, &prop)) + if (prop.vt == VT_UI4) + { + _fi.Attrib = prop.ulVal; + _fi.Attrib_Defined = true; + } + else if (prop.vt != VT_EMPTY) + return E_FAIL; + } + + RINOK(GetTime(index, kpidCTime, _fi.CTime)) + RINOK(GetTime(index, kpidATime, _fi.ATime)) + RINOK(GetTime(index, kpidMTime, _fi.MTime)) + + #ifndef _WIN32 + if (_ntOptions.ExtractOwner) + { + // SendMessageError_with_LastError("_ntOptions.ExtractOwner", _diskFilePath); + GetOwner(archive, index, kpidUser, kpidUserId, _fi.Owner); + GetOwner(archive, index, kpidGroup, kpidGroupId, _fi.Group); + } + #endif + + return S_OK; +} + + + +void CArchiveExtractCallback::CorrectPathParts() +{ + UStringVector &pathParts = _item.PathParts; + + #ifdef SUPPORT_ALT_STREAMS + if (!_item.IsAltStream + || !pathParts.IsEmpty() + || !(_removePartsForAltStreams || _pathMode == NExtract::NPathMode::kNoPathsAlt)) #endif + Correct_FsPath(_pathMode == NExtract::NPathMode::kAbsPaths, _keepAndReplaceEmptyDirPrefixes, pathParts, _item.MainIsDir); + + #ifdef SUPPORT_ALT_STREAMS + + if (_item.IsAltStream) + { + UString s (_item.AltStreamName); + Correct_AltStream_Name(s); + bool needColon = true; + + if (pathParts.IsEmpty()) + { + pathParts.AddNew(); + if (_removePartsForAltStreams || _pathMode == NExtract::NPathMode::kNoPathsAlt) + needColon = false; + } + #ifdef _WIN32 + else if (_pathMode == NExtract::NPathMode::kAbsPaths && + NWildcard::GetNumPrefixParts_if_DrivePath(pathParts) == pathParts.Size()) + pathParts.AddNew(); + #endif + + UString &name = pathParts.Back(); + if (needColon) + name += (char)(_ntOptions.ReplaceColonForAltStream ? '_' : ':'); + name += s; + } + + #endif // SUPPORT_ALT_STREAMS +} + + +void CArchiveExtractCallback::GetFiTimesCAM(CFiTimesCAM &pt) +{ + pt.CTime_Defined = false; + pt.ATime_Defined = false; + pt.MTime_Defined = false; + + if (Write_MTime) + { + if (_fi.MTime.Def) + { + _fi.MTime.Write_To_FiTime(pt.MTime); + pt.MTime_Defined = true; + } + else if (_arc->MTime.Def) + { + _arc->MTime.Write_To_FiTime(pt.MTime); + pt.MTime_Defined = true; + } + } + + if (Write_CTime && _fi.CTime.Def) + { + _fi.CTime.Write_To_FiTime(pt.CTime); + pt.CTime_Defined = true; + } + + if (Write_ATime && _fi.ATime.Def) + { + _fi.ATime.Write_To_FiTime(pt.ATime); + pt.ATime_Defined = true; + } +} + + +void CArchiveExtractCallback::CreateFolders() +{ + // 21.04 : we don't change original (_item.PathParts) here + UStringVector pathParts = _item.PathParts; + + if (!pathParts.IsEmpty()) + { + /* v23: if we extract symlink, and we know that it links to dir: + Linux: we don't create dir item (symlink_from_path) here. + Windows: SetReparseData() will create dir item, if it doesn't exist, + but if we create dir item here, it's not problem. */ + if (!_item.IsDir + #ifdef SUPPORT_LINKS + #ifndef WIN32 + || !_link.linkPath.IsEmpty() + #endif + #endif + ) + pathParts.DeleteBack(); + } + + if (pathParts.IsEmpty()) + return; + + FString fullPathNew; + CreateComplexDirectory(pathParts, fullPathNew); + + if (!_item.IsDir) + return; + + if (_itemFailure) + return; + + CDirPathTime pt; + GetFiTimesCAM(pt); + + if (pt.IsSomeTimeDefined()) + { + pt.Path = fullPathNew; + pt.SetDirTime(); + _extractedFolders.Add(pt); + } +} + + + +/* + CheckExistFile(fullProcessedPath) + it can change: fullProcessedPath, _isRenamed, _overwriteMode + (needExit = true) means that we must exit GetStream() even for S_OK result. +*/ + +HRESULT CArchiveExtractCallback::CheckExistFile(FString &fullProcessedPath, bool &needExit) +{ + needExit = true; // it was set already before + + NFind::CFileInfo fileInfo; + + if (fileInfo.Find(fullProcessedPath)) + { + if (_overwriteMode == NExtract::NOverwriteMode::kSkip) + return S_OK; + + if (_overwriteMode == NExtract::NOverwriteMode::kAsk) + { + const int slashPos = fullProcessedPath.ReverseFind_PathSepar(); + const FString realFullProcessedPath = fullProcessedPath.Left((unsigned)(slashPos + 1)) + fileInfo.Name; + + /* (fileInfo) can be symbolic link. + we can show final file properties here. */ + + FILETIME ft1; + FiTime_To_FILETIME(fileInfo.MTime, ft1); + + Int32 overwriteResult; + RINOK(_extractCallback2->AskOverwrite( + fs2us(realFullProcessedPath), &ft1, &fileInfo.Size, _item.Path, + _fi.MTime.Def ? &_fi.MTime.FT : NULL, + _curSize_Defined ? &_curSize : NULL, + &overwriteResult)) + + switch (overwriteResult) + { + case NOverwriteAnswer::kCancel: + return E_ABORT; + case NOverwriteAnswer::kNo: + return S_OK; + case NOverwriteAnswer::kNoToAll: + _overwriteMode = NExtract::NOverwriteMode::kSkip; + return S_OK; + + case NOverwriteAnswer::kYes: + break; + case NOverwriteAnswer::kYesToAll: + _overwriteMode = NExtract::NOverwriteMode::kOverwrite; + break; + case NOverwriteAnswer::kAutoRename: + _overwriteMode = NExtract::NOverwriteMode::kRename; + break; + default: + return E_FAIL; + } + } // NExtract::NOverwriteMode::kAsk + + if (_overwriteMode == NExtract::NOverwriteMode::kRename) + { + if (!AutoRenamePath(fullProcessedPath)) + { + RINOK(SendMessageError(kCantAutoRename, fullProcessedPath)) + return E_FAIL; + } + _isRenamed = true; + } + else if (_overwriteMode == NExtract::NOverwriteMode::kRenameExisting) + { + FString existPath (fullProcessedPath); + if (!AutoRenamePath(existPath)) + { + RINOK(SendMessageError(kCantAutoRename, fullProcessedPath)) + return E_FAIL; + } + // MyMoveFile can rename folders. So it's OK to use it for folders too + if (!MyMoveFile(fullProcessedPath, existPath)) + { + HRESULT errorCode = GetLastError_noZero_HRESULT(); + RINOK(SendMessageError2(errorCode, kCantRenameFile, existPath, fullProcessedPath)) + return E_FAIL; + } + } + else // not Rename* + { + if (fileInfo.IsDir()) + { + // do we need to delete all files in folder? + if (!RemoveDir(fullProcessedPath)) + { + RINOK(SendMessageError_with_LastError(kCantDeleteOutputDir, fullProcessedPath)) + return S_OK; + } + } + else // fileInfo is not Dir + { + if (NFind::DoesFileExist_Raw(fullProcessedPath)) + if (!DeleteFileAlways(fullProcessedPath)) + if (GetLastError() != ERROR_FILE_NOT_FOUND) // check it in linux + { + RINOK(SendMessageError_with_LastError(kCantDeleteOutputFile, fullProcessedPath)) + return S_OK; + // return E_FAIL; + } + } // fileInfo is not Dir + } // not Rename* + } + else // not Find(fullProcessedPath) + { + #if defined(_WIN32) && !defined(UNDER_CE) + // we need to clear READ-ONLY of parent before creating alt stream + int colonPos = NName::FindAltStreamColon(fullProcessedPath); + if (colonPos >= 0 && fullProcessedPath[(unsigned)colonPos + 1] != 0) + { + FString parentFsPath (fullProcessedPath); + parentFsPath.DeleteFrom((unsigned)colonPos); + NFind::CFileInfo parentFi; + if (parentFi.Find(parentFsPath)) + { + if (parentFi.IsReadOnly()) + SetFileAttrib(parentFsPath, parentFi.Attrib & ~(DWORD)FILE_ATTRIBUTE_READONLY); + } + } + #endif // defined(_WIN32) && !defined(UNDER_CE) + } - RINOK(Archive_GetItemBoolProp(archive, index, kpidEncrypted, _encrypted)); + needExit = false; + return S_OK; +} + + + + + + +HRESULT CArchiveExtractCallback::GetExtractStream(CMyComPtr<ISequentialOutStream> &outStreamLoc, bool &needExit) +{ + needExit = true; + + RINOK(Read_fi_Props()) + + #ifdef SUPPORT_LINKS + IInArchive *archive = _arc->Archive; + #endif + + const UInt32 index = _index; - RINOK(GetUnpackSize()); + bool isAnti = false; + RINOK(_arc->IsItem_Anti(index, isAnti)) + + CorrectPathParts(); + UString processedPath (MakePathFromParts(_item.PathParts)); + + if (!isAnti) + { + // 21.04: CreateFolders doesn't change (_item.PathParts) + CreateFolders(); + } + + FString fullProcessedPath (us2fs(processedPath)); + if (_pathMode != NExtract::NPathMode::kAbsPaths + || !NName::IsAbsolutePath(processedPath)) + { + fullProcessedPath = MakePath_from_2_Parts(_dirPathPrefix, fullProcessedPath); + } #ifdef SUPPORT_ALT_STREAMS + if (_item.IsAltStream && _item.ParentIndex != (UInt32)(Int32)-1) + { + const int renIndex = _renamedFiles.FindInSorted(CIndexToPathPair(_item.ParentIndex)); + if (renIndex != -1) + { + const CIndexToPathPair &pair = _renamedFiles[(unsigned)renIndex]; + fullProcessedPath = pair.Path; + fullProcessedPath += ':'; + UString s (_item.AltStreamName); + Correct_AltStream_Name(s); + fullProcessedPath += us2fs(s); + } + } + #endif // SUPPORT_ALT_STREAMS + + if (_item.IsDir) + { + _diskFilePath = fullProcessedPath; + if (isAnti) + RemoveDir(_diskFilePath); + #ifdef SUPPORT_LINKS + if (_link.linkPath.IsEmpty()) + #endif + { + if (!isAnti) + SetAttrib(); + return S_OK; + } + } + else if (!_isSplit) + { + RINOK(CheckExistFile(fullProcessedPath, needExit)) + if (needExit) + return S_OK; + needExit = true; + } - if (!_ntOptions.AltStreams.Val && _item.IsAltStream) + _diskFilePath = fullProcessedPath; + + + if (isAnti) + { + needExit = false; return S_OK; + } + + // not anti + + #ifdef SUPPORT_LINKS + + if (!_link.linkPath.IsEmpty()) + { + #ifndef UNDER_CE + { + bool linkWasSet = false; + RINOK(SetFromLinkPath(fullProcessedPath, _link, linkWasSet)) + if (linkWasSet) + { + _isSymLinkCreated = _link.IsSymLink(); + SetAttrib(); + // printf("\nlinkWasSet %s\n", GetAnsiString(_diskFilePath)); + } + } + #endif // UNDER_CE + + // if (_copyFile_Path.IsEmpty()) + { + needExit = false; + return S_OK; + } + } + + if (!_hardLinks.IDs.IsEmpty() && !_item.IsAltStream && !_item.IsDir) + { + CHardLinkNode h; + bool defined; + RINOK(Archive_Get_HardLinkNode(archive, index, h, defined)) + if (defined) + { + const int linkIndex = _hardLinks.IDs.FindInSorted2(h); + if (linkIndex != -1) + { + FString &hl = _hardLinks.Links[(unsigned)linkIndex]; + if (hl.IsEmpty()) + hl = fullProcessedPath; + else + { + if (!MyCreateHardLink(fullProcessedPath, hl)) + { + HRESULT errorCode = GetLastError_noZero_HRESULT(); + RINOK(SendMessageError2(errorCode, kCantCreateHardLink, fullProcessedPath, hl)) + return S_OK; + } + + // printf("\nHard linkWasSet Archive_Get_HardLinkNode %s\n", GetAnsiString(_diskFilePath)); + // _needSetAttrib = true; // do we need to set attribute ? + SetAttrib(); + needExit = false; + return S_OK; + } + } + } + } + + #endif // SUPPORT_LINKS + + + // ---------- CREATE WRITE FILE ----- + + _outFileStreamSpec = new COutFileStream; + CMyComPtr<IOutStream> outFileStream_Loc(_outFileStreamSpec); + + if (!_outFileStreamSpec->Open(fullProcessedPath, _isSplit ? OPEN_ALWAYS: CREATE_ALWAYS)) + { + // if (::GetLastError() != ERROR_FILE_EXISTS || !isSplit) + { + RINOK(SendMessageError_with_LastError(kCantOpenOutFile, fullProcessedPath)) + return S_OK; + } + } + + _needSetAttrib = true; + bool is_SymLink_in_Data = false; + + if (_curSize_Defined && _curSize > 0 && _curSize < (1 << 12)) + { + if (_fi.IsLinuxSymLink()) + { + is_SymLink_in_Data = true; + _is_SymLink_in_Data_Linux = true; + } + else if (_fi.IsReparse()) + { + is_SymLink_in_Data = true; + _is_SymLink_in_Data_Linux = false; + } + } + + if (is_SymLink_in_Data) + { + _outMemBuf.Alloc((size_t)_curSize); + _bufPtrSeqOutStream_Spec = new CBufPtrSeqOutStream; + _bufPtrSeqOutStream = _bufPtrSeqOutStream_Spec; + _bufPtrSeqOutStream_Spec->Init(_outMemBuf, _outMemBuf.Size()); + outStreamLoc = _bufPtrSeqOutStream; + } + else // not reprase + { + if (_ntOptions.PreAllocateOutFile && !_isSplit && _curSize_Defined && _curSize > (1 << 12)) + { + // UInt64 ticks = GetCpuTicks(); + _fileLength_that_WasSet = _curSize; + bool res = _outFileStreamSpec->File.SetLength(_curSize); + _fileLength_WasSet = res; + + // ticks = GetCpuTicks() - ticks; + // printf("\nticks = %10d\n", (unsigned)ticks); + if (!res) + { + RINOK(SendMessageError_with_LastError(kCantSetFileLen, fullProcessedPath)) + } + + /* + _outFileStreamSpec->File.Close(); + ticks = GetCpuTicks() - ticks; + printf("\nticks = %10d\n", (unsigned)ticks); + return S_FALSE; + */ + + /* + File.SetLength() on FAT (xp64): is fast, but then File.Close() can be slow, + if we don't write any data. + File.SetLength() for remote share file (exFAT) can be slow in some cases, + and the Windows can return "network error" after 1 minute, + while remote file still can grow. + We need some way to detect such bad cases and disable PreAllocateOutFile mode. + */ + + res = _outFileStreamSpec->SeekToBegin_bool(); + if (!res) + { + RINOK(SendMessageError_with_LastError("Cannot seek to begin of file", fullProcessedPath)) + } + } // PreAllocateOutFile + + #ifdef SUPPORT_ALT_STREAMS + if (_isRenamed && !_item.IsAltStream) + { + CIndexToPathPair pair(index, fullProcessedPath); + unsigned oldSize = _renamedFiles.Size(); + unsigned insertIndex = _renamedFiles.AddToUniqueSorted(pair); + if (oldSize == _renamedFiles.Size()) + _renamedFiles[insertIndex].Path = fullProcessedPath; + } + #endif // SUPPORT_ALT_STREAMS + + if (_isSplit) + { + RINOK(outFileStream_Loc->Seek((Int64)_position, STREAM_SEEK_SET, NULL)) + } + outStreamLoc = outFileStream_Loc; + } // if not reprase + + _outFileStream = outFileStream_Loc; + + needExit = false; + return S_OK; +} + + + +HRESULT CArchiveExtractCallback::GetItem(UInt32 index) +{ + #ifndef Z7_SFX + _item._use_baseParentFolder_mode = _use_baseParentFolder_mode; + if (_use_baseParentFolder_mode) + { + _item._baseParentFolder = (int)_baseParentFolder; + if (_pathMode == NExtract::NPathMode::kFullPaths || + _pathMode == NExtract::NPathMode::kAbsPaths) + _item._baseParentFolder = -1; + } + #endif // Z7_SFX + + #ifdef SUPPORT_ALT_STREAMS + _item.WriteToAltStreamIfColon = _ntOptions.WriteToAltStreamIfColon; #endif + return _arc->GetItem(index, _item); +} + + +Z7_COM7F_IMF(CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode)) +{ + COM_TRY_BEGIN + + *outStream = NULL; + + #ifndef Z7_SFX + if (_hashStream) + _hashStreamSpec->ReleaseStream(); + _hashStreamWasUsed = false; + #endif + _outFileStream.Release(); + _bufPtrSeqOutStream.Release(); + + _encrypted = false; + _position = 0; + _isSplit = false; + + _curSize = 0; + _curSize_Defined = false; + _fileLength_WasSet = false; + _fileLength_that_WasSet = 0; + _index = index; + + _diskFilePath.Empty(); + + _isRenamed = false; + + // _fi.Clear(); + + // _is_SymLink_in_Data = false; + _is_SymLink_in_Data_Linux = false; + + _needSetAttrib = false; + _isSymLinkCreated = false; + _itemFailure = false; + + #ifdef SUPPORT_LINKS + // _copyFile_Path.Empty(); + _link.Clear(); + #endif + + _extractMode = false; + + switch (askExtractMode) + { + case NArchive::NExtract::NAskMode::kExtract: + if (_testMode) + { + // askExtractMode = NArchive::NExtract::NAskMode::kTest; + } + else + _extractMode = true; + break; + } + + + IInArchive *archive = _arc->Archive; + + RINOK(GetItem(index)) + + { + NCOM::CPropVariant prop; + RINOK(archive->GetProperty(index, kpidPosition, &prop)) + if (prop.vt != VT_EMPTY) + { + if (prop.vt != VT_UI8) + return E_FAIL; + _position = prop.uhVal.QuadPart; + _isSplit = true; + } + } + + #ifdef SUPPORT_LINKS + RINOK(ReadLink()) + #endif // SUPPORT_LINKS + + + RINOK(Archive_GetItemBoolProp(archive, index, kpidEncrypted, _encrypted)) + + RINOK(GetUnpackSize()) + + #ifdef SUPPORT_ALT_STREAMS + if (!_ntOptions.AltStreams.Val && _item.IsAltStream) + return S_OK; + #endif // SUPPORT_ALT_STREAMS + + // we can change (_item.PathParts) in this function UStringVector &pathParts = _item.PathParts; if (_wildcardCensor) @@ -805,7 +1649,7 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre return S_OK; } - #ifndef _SFX + #ifndef Z7_SFX if (_use_baseParentFolder_mode) { if (!pathParts.IsEmpty()) @@ -824,7 +1668,7 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre } } else - #endif + #endif // Z7_SFX { if (pathParts.IsEmpty()) { @@ -907,17 +1751,16 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre numRemovePathParts = pathParts.Size() - 1; break; } - /* - case NExtract::NPathMode::kFullPaths: case NExtract::NPathMode::kAbsPaths: + // default: break; - */ } pathParts.DeleteFrontal(numRemovePathParts); } - #ifndef _SFX + + #ifndef Z7_SFX if (ExtractToStreamCallback) { @@ -928,13 +1771,13 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre } GetProp_Spec->Arc = _arc; GetProp_Spec->IndexInArc = index; - UString name = MakePathFromParts(pathParts); + UString name (MakePathFromParts(pathParts)); #ifdef SUPPORT_ALT_STREAMS if (_item.IsAltStream) { if (!pathParts.IsEmpty() || (!_removePartsForAltStreams && _pathMode != NExtract::NPathMode::kNoPathsAlt)) - name += L':'; + name += ':'; name += _item.AltStreamName; } #endif @@ -942,500 +1785,531 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre return ExtractToStreamCallback->GetStream7(name, BoolToInt(_item.IsDir), outStream, askExtractMode, GetProp); } - #endif + #endif // Z7_SFX + CMyComPtr<ISequentialOutStream> outStreamLoc; -if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode) -{ - if (_stdOutMode) + if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode) { - outStreamLoc = new CStdOutFileStream; + if (_stdOutMode) + outStreamLoc = new CStdOutFileStream; + else + { + bool needExit = true; + RINOK(GetExtractStream(outStreamLoc, needExit)) + if (needExit) + return S_OK; + } } - else + + #ifndef Z7_SFX + if (_hashStream) { + if (askExtractMode == NArchive::NExtract::NAskMode::kExtract || + askExtractMode == NArchive::NExtract::NAskMode::kTest) { - NCOM::CPropVariant prop; - RINOK(archive->GetProperty(index, kpidAttrib, &prop)); - if (prop.vt == VT_UI4) - { - _fi.Attrib = prop.ulVal; - _fi.AttribDefined = true; - } - else if (prop.vt == VT_EMPTY) - _fi.AttribDefined = false; - else - return E_FAIL; + _hashStreamSpec->SetStream(outStreamLoc); + outStreamLoc = _hashStream; + _hashStreamSpec->Init(true); + _hashStreamWasUsed = true; } + } + #endif // Z7_SFX - RINOK(GetTime(index, kpidCTime, _fi.CTime, _fi.CTimeDefined)); - RINOK(GetTime(index, kpidATime, _fi.ATime, _fi.ATimeDefined)); - RINOK(GetTime(index, kpidMTime, _fi.MTime, _fi.MTimeDefined)); + if (outStreamLoc) + { + /* + #ifdef SUPPORT_LINKS + if (!_copyFile_Path.IsEmpty()) + { + RINOK(PrepareOperation(askExtractMode)); + RINOK(MyCopyFile(outStreamLoc)); + return SetOperationResult(NArchive::NExtract::NOperationResult::kOK); + } + if (_link.isCopyLink && _testMode) + return S_OK; + #endif + */ + *outStream = outStreamLoc.Detach(); + } + + return S_OK; - bool isAnti = false; - RINOK(_arc->IsItemAnti(index, isAnti)); + COM_TRY_END +} - #ifdef SUPPORT_ALT_STREAMS - if (!_item.IsAltStream - || !pathParts.IsEmpty() - || !(_removePartsForAltStreams || _pathMode == NExtract::NPathMode::kNoPathsAlt)) - #endif - Correct_FsPath(_pathMode == NExtract::NPathMode::kAbsPaths, pathParts, _item.MainIsDir); - #ifdef SUPPORT_ALT_STREAMS - - if (_item.IsAltStream) - { - UString s = _item.AltStreamName; - Correct_AltStream_Name(s); - bool needColon = true; - if (pathParts.IsEmpty()) - { - pathParts.AddNew(); - if (_removePartsForAltStreams || _pathMode == NExtract::NPathMode::kNoPathsAlt) - needColon = false; - } - else if (_pathMode == NExtract::NPathMode::kAbsPaths && - NWildcard::GetNumPrefixParts_if_DrivePath(pathParts) == pathParts.Size()) - pathParts.AddNew(); - - UString &name = pathParts.Back(); - if (needColon) - name += (wchar_t)(_ntOptions.ReplaceColonForAltStream ? L'_' : L':'); - name += s; - } - - #endif - UString processedPath = MakePathFromParts(pathParts); - - if (!isAnti) - { - if (!_item.IsDir) - { - if (!pathParts.IsEmpty()) - pathParts.DeleteBack(); - } - - if (!pathParts.IsEmpty()) - { - FString fullPathNew; - CreateComplexDirectory(pathParts, fullPathNew); - if (_item.IsDir) - { - _extractedFolderPaths.Add(fullPathNew); - _extractedFolderIndices.Add(index); - SetDirTime(fullPathNew, - (WriteCTime && _fi.CTimeDefined) ? &_fi.CTime : NULL, - (WriteATime && _fi.ATimeDefined) ? &_fi.ATime : NULL, - (WriteMTime && _fi.MTimeDefined) ? &_fi.MTime : (_arc->MTimeDefined ? &_arc->MTime : NULL)); - } - } - } - FString fullProcessedPath = us2fs(processedPath); - if (_pathMode != NExtract::NPathMode::kAbsPaths - || !NName::IsAbsolutePath(processedPath)) + + + + + +Z7_COM7F_IMF(CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode)) +{ + COM_TRY_BEGIN + + #ifndef Z7_SFX + if (ExtractToStreamCallback) + return ExtractToStreamCallback->PrepareOperation7(askExtractMode); + #endif + + _extractMode = false; + + switch (askExtractMode) + { + case NArchive::NExtract::NAskMode::kExtract: + if (_testMode) + askExtractMode = NArchive::NExtract::NAskMode::kTest; + else + _extractMode = true; + break; + } + + return _extractCallback2->PrepareOperation(_item.Path, BoolToInt(_item.IsDir), + askExtractMode, _isSplit ? &_position: NULL); + + COM_TRY_END +} + + + + + +HRESULT CArchiveExtractCallback::CloseFile() +{ + if (!_outFileStream) + return S_OK; + + HRESULT hres = S_OK; + + const UInt64 processedSize = _outFileStreamSpec->ProcessedSize; + if (_fileLength_WasSet && _fileLength_that_WasSet > processedSize) + { + const bool res = _outFileStreamSpec->File.SetLength(processedSize); + _fileLength_WasSet = res; + if (!res) { - fullProcessedPath = MakePath_from_2_Parts(_dirPathPrefix, fullProcessedPath); + const HRESULT hres2 = SendMessageError_with_LastError(kCantSetFileLen, us2fs(_item.Path)); + if (hres == S_OK) + hres = hres2; } + } - #ifdef SUPPORT_ALT_STREAMS - - if (_item.IsAltStream && _item.ParentIndex != (UInt32)(Int32)-1) + _curSize = processedSize; + _curSize_Defined = true; + + #if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX) + if (ZoneBuf.Size() != 0 + && !_item.IsAltStream) + { + // if (NFind::DoesFileExist_Raw(tempFilePath)) + if (ZoneMode != NExtract::NZoneIdMode::kOffice || + FindExt2(kOfficeExtensions, fs2us(_diskFilePath))) { - int renIndex = _renamedFiles.FindInSorted(CIndexToPathPair(_item.ParentIndex)); - if (renIndex >= 0) + // we must write zone file before setting of timestamps + const FString path = _diskFilePath + k_ZoneId_StreamName; + if (!WriteZoneFile(path, ZoneBuf)) { - const CIndexToPathPair &pair = _renamedFiles[renIndex]; - fullProcessedPath = pair.Path; - fullProcessedPath += (FChar)':'; - UString s = _item.AltStreamName; - Correct_AltStream_Name(s); - fullProcessedPath += us2fs(s); + // we can't write it in FAT + // SendMessageError_with_LastError("Can't write Zone.Identifier stream", path); } } - - #endif + } + #endif - bool isRenamed = false; + CFiTimesCAM t; + GetFiTimesCAM(t); - if (_item.IsDir) + // #ifdef _WIN32 + if (t.IsSomeTimeDefined()) + _outFileStreamSpec->SetTime( + t.CTime_Defined ? &t.CTime : NULL, + t.ATime_Defined ? &t.ATime : NULL, + t.MTime_Defined ? &t.MTime : NULL); + // #endif + + RINOK(_outFileStreamSpec->Close()) + _outFileStream.Release(); + return hres; +} + + +#ifdef SUPPORT_LINKS + + +HRESULT CArchiveExtractCallback::SetFromLinkPath( + const FString &fullProcessedPath, + const CLinkInfo &linkInfo, + bool &linkWasSet) +{ + linkWasSet = false; + if (!_ntOptions.SymLinks.Val && !linkInfo.isHardLink) + return S_OK; + + UString relatPath; + + /* if (linkInfo.isRelative) + linkInfo.linkPath is final link path that must be stored to file link field + else + linkInfo.linkPath is path from root of archive. So we must add _dirPathPrefix_Full before linkPath. + */ + + if (linkInfo.isRelative) + relatPath = GetDirPrefixOf(_item.Path); + relatPath += linkInfo.linkPath; + + if (!IsSafePath(relatPath)) + { + return SendMessageError2( + 0, // errorCode + "Dangerous link path was ignored", + us2fs(_item.Path), + us2fs(linkInfo.linkPath)); // us2fs(relatPath) + } + + FString existPath; + if (linkInfo.isHardLink /* || linkInfo.IsCopyLink */ || !linkInfo.isRelative) + { + if (!NName::GetFullPath(_dirPathPrefix_Full, us2fs(relatPath), existPath)) { - _diskFilePath = fullProcessedPath; - if (isAnti) - RemoveDir(_diskFilePath); - #ifdef SUPPORT_LINKS - if (linkPath.IsEmpty()) - #endif - return S_OK; + RINOK(SendMessageError("Incorrect path", us2fs(relatPath))) } - else if (!_isSplit) - { + } + else + { + existPath = us2fs(linkInfo.linkPath); + // printf("\nlinkPath = : %s\n", GetOemString(linkInfo.linkPath).Ptr()); + } - // ----- Is file (not split) ----- - NFind::CFileInfo fileInfo; - if (fileInfo.Find(fullProcessedPath)) + if (existPath.IsEmpty()) + return SendMessageError("Empty link", fullProcessedPath); + + if (linkInfo.isHardLink /* || linkInfo.IsCopyLink */) + { + // if (linkInfo.isHardLink) { - switch (_overwriteMode) + if (!MyCreateHardLink(fullProcessedPath, existPath)) { - case NExtract::NOverwriteMode::kSkip: - return S_OK; - case NExtract::NOverwriteMode::kAsk: - { - int slashPos = fullProcessedPath.ReverseFind_PathSepar(); - FString realFullProcessedPath = fullProcessedPath.Left(slashPos + 1) + fileInfo.Name; - - Int32 overwriteResult; - RINOK(_extractCallback2->AskOverwrite( - fs2us(realFullProcessedPath), &fileInfo.MTime, &fileInfo.Size, _item.Path, - _fi.MTimeDefined ? &_fi.MTime : NULL, - _curSizeDefined ? &_curSize : NULL, - &overwriteResult)) - - switch (overwriteResult) - { - case NOverwriteAnswer::kCancel: return E_ABORT; - case NOverwriteAnswer::kNo: return S_OK; - case NOverwriteAnswer::kNoToAll: _overwriteMode = NExtract::NOverwriteMode::kSkip; return S_OK; - case NOverwriteAnswer::kYes: break; - case NOverwriteAnswer::kYesToAll: _overwriteMode = NExtract::NOverwriteMode::kOverwrite; break; - case NOverwriteAnswer::kAutoRename: _overwriteMode = NExtract::NOverwriteMode::kRename; break; - default: - return E_FAIL; - } - } + const HRESULT errorCode = GetLastError_noZero_HRESULT(); + RINOK(SendMessageError2(errorCode, kCantCreateHardLink, fullProcessedPath, existPath)) } - if (_overwriteMode == NExtract::NOverwriteMode::kRename) + linkWasSet = true; + return S_OK; + } + /* + // IsCopyLink + { + NFind::CFileInfo fi; + if (!fi.Find(existPath)) { - if (!AutoRenamePath(fullProcessedPath)) - { - RINOK(SendMessageError(kCantAutoRename, fullProcessedPath)); - return E_FAIL; - } - isRenamed = true; - } - else if (_overwriteMode == NExtract::NOverwriteMode::kRenameExisting) - { - FString existPath = fullProcessedPath; - if (!AutoRenamePath(existPath)) - { - RINOK(SendMessageError(kCantAutoRename, fullProcessedPath)); - return E_FAIL; - } - // MyMoveFile can raname folders. So it's OK to use it for folders too - if (!MyMoveFile(fullProcessedPath, existPath)) - { - RINOK(SendMessageError2(kCantRenameFile, existPath, fullProcessedPath)); - return E_FAIL; - } + RINOK(SendMessageError2("Cannot find the file for copying", existPath, fullProcessedPath)); } else { - if (fileInfo.IsDir()) - { - // do we need to delete all files in folder? - if (!RemoveDir(fullProcessedPath)) - { - RINOK(SendMessageError_with_LastError(kCantDeleteOutputDir, fullProcessedPath)); - return S_OK; - } - } + if (_curSize_Defined && _curSize == fi.Size) + _copyFile_Path = existPath; else { - bool needDelete = true; - if (needDelete) - { - if (!DeleteFileAlways(fullProcessedPath)) - { - RINOK(SendMessageError_with_LastError(kCantDeleteOutputFile, fullProcessedPath)); - return S_OK; - // return E_FAIL; - } - } + RINOK(SendMessageError2("File size collision for file copying", existPath, fullProcessedPath)); } + // RINOK(MyCopyFile(existPath, fullProcessedPath)); } } - else // not Find(fullProcessedPath) - { - // we need to clear READ-ONLY of parent before creating alt stream - #if defined(_WIN32) && !defined(UNDER_CE) - int colonPos = NName::FindAltStreamColon(fullProcessedPath); - if (colonPos >= 0 && fullProcessedPath[(unsigned)colonPos + 1] != 0) + */ + } + + // is Symbolic link + + /* + if (_item.IsDir && !isRelative) + { + // Windows before Vista doesn't support symbolic links. + // we could convert such symbolic links to Junction Points + // isJunction = true; + // convertToAbs = true; + } + */ + + if (!_ntOptions.SymLinks_AllowDangerous.Val) + { + #ifdef _WIN32 + if (_item.IsDir) + #endif + if (linkInfo.isRelative) { - FString parentFsPath = fullProcessedPath; - parentFsPath.DeleteFrom(colonPos); - NFind::CFileInfo parentFi; - if (parentFi.Find(parentFsPath)) + CLinkLevelsInfo levelsInfo; + levelsInfo.Parse(linkInfo.linkPath); + if (levelsInfo.FinalLevel < 1 || levelsInfo.IsAbsolute) { - if (parentFi.IsReadOnly()) - SetFileAttrib(parentFsPath, parentFi.Attrib & ~FILE_ATTRIBUTE_READONLY); + return SendMessageError2( + 0, // errorCode + "Dangerous symbolic link path was ignored", + us2fs(_item.Path), + us2fs(linkInfo.linkPath)); } } - #endif - } - // ----- END of code for Is file (not split) ----- + } - } - _diskFilePath = fullProcessedPath; - + + #ifdef _WIN32 + + CByteBuffer data; + // printf("\nFillLinkData(): %s\n", GetOemString(existPath).Ptr()); + if (!FillLinkData(data, fs2us(existPath), !linkInfo.isJunction, linkInfo.isWSL)) + return SendMessageError("Cannot fill link data", us2fs(_item.Path)); - if (!isAnti) - { - #ifdef SUPPORT_LINKS + /* + if (NtReparse_Size != data.Size() || memcmp(NtReparse_Data, data, data.Size()) != 0) + { + SendMessageError("reconstructed Reparse is different", fs2us(existPath)); + } + */ + + CReparseAttr attr; + if (!attr.Parse(data, data.Size())) + { + RINOK(SendMessageError("Internal error for symbolic link file", us2fs(_item.Path))) + return S_OK; + } + if (!NFile::NIO::SetReparseData(fullProcessedPath, _item.IsDir, data, (DWORD)data.Size())) + { + RINOK(SendMessageError_with_LastError(kCantCreateSymLink, fullProcessedPath)) + return S_OK; + } + linkWasSet = true; - if (!linkPath.IsEmpty()) - { - #ifndef UNDER_CE + return S_OK; + + + #else // ! _WIN32 - UString relatPath; - if (isRelative) - relatPath = GetDirPrefixOf(_item.Path); - relatPath += linkPath; - - if (!IsSafePath(relatPath)) - { - RINOK(SendMessageError("Dangerous link path was ignored", us2fs(relatPath))); - } - else - { - FString existPath; - if (isHardLink /* || isCopyLink */ || !isRelative) - { - if (!NName::GetFullPath(_dirPathPrefix_Full, us2fs(relatPath), existPath)) - { - RINOK(SendMessageError("Incorrect path", us2fs(relatPath))); - } - } - else - { - existPath = us2fs(linkPath); - } - - if (!existPath.IsEmpty()) - { - if (isHardLink /* || isCopyLink */) - { - // if (isHardLink) - { - if (!MyCreateHardLink(fullProcessedPath, existPath)) - { - RINOK(SendMessageError2("Can not create hard link", fullProcessedPath, existPath)); - // return S_OK; - } - } - /* - else - { - NFind::CFileInfo fi; - if (!fi.Find(existPath)) - { - RINOK(SendMessageError2("Can not find the file for copying", existPath, fullProcessedPath)); - } - else - { - if (_curSizeDefined && _curSize == fi.Size) - _CopyFile_Path = existPath; - else - { - RINOK(SendMessageError2("File size collision for file copying", existPath, fullProcessedPath)); - } - - // RINOK(MyCopyFile(existPath, fullProcessedPath)); - } - } - */ - } - else if (_ntOptions.SymLinks.Val) - { - // bool isSymLink = true; // = false for junction - if (_item.IsDir && !isRelative) - { - // if it's before Vista we use Junction Point - // isJunction = true; - // convertToAbs = true; - } - - CByteBuffer data; - if (FillLinkData(data, fs2us(existPath), !isJunction)) - { - CReparseAttr attr; - if (!attr.Parse(data, data.Size())) - { - RINOK(SendMessageError("Internal error for symbolic link file", us2fs(_item.Path))); - // return E_FAIL; - } - else - if (!NFile::NIO::SetReparseData(fullProcessedPath, _item.IsDir, data, (DWORD)data.Size())) - { - RINOK(SendMessageError_with_LastError("Can not create symbolic link", fullProcessedPath)); - } - } - } - } - } - - #endif - } - - if (linkPath.IsEmpty() /* || !_CopyFile_Path.IsEmpty() */) - #endif // SUPPORT_LINKS - { - bool needWriteFile = true; - - #ifdef SUPPORT_LINKS - if (!_hardLinks.IDs.IsEmpty() && !_item.IsAltStream) - { - CHardLinkNode h; - bool defined; - RINOK(Archive_Get_HardLinkNode(archive, index, h, defined)); - if (defined) - { - { - int linkIndex = _hardLinks.IDs.FindInSorted2(h); - if (linkIndex >= 0) - { - FString &hl = _hardLinks.Links[linkIndex]; - if (hl.IsEmpty()) - hl = fullProcessedPath; - else - { - if (!MyCreateHardLink(fullProcessedPath, hl)) - { - RINOK(SendMessageError2("Can not create hard link", fullProcessedPath, hl)); - return S_OK; - } - needWriteFile = false; - } - } - } - } - } - #endif - - if (needWriteFile) - { - _outFileStreamSpec = new COutFileStream; - CMyComPtr<ISequentialOutStream> outStreamLoc2(_outFileStreamSpec); - if (!_outFileStreamSpec->Open(fullProcessedPath, _isSplit ? OPEN_ALWAYS: CREATE_ALWAYS)) - { - // if (::GetLastError() != ERROR_FILE_EXISTS || !isSplit) - { - RINOK(SendMessageError_with_LastError("Can not open output file", fullProcessedPath)); - return S_OK; - } - } + if (!NFile::NIO::SetSymLink(fullProcessedPath, existPath)) + { + RINOK(SendMessageError_with_LastError(kCantCreateSymLink, fullProcessedPath)) + return S_OK; + } + linkWasSet = true; + return S_OK; - #ifdef SUPPORT_ALT_STREAMS - if (isRenamed && !_item.IsAltStream) - { - CIndexToPathPair pair(index, fullProcessedPath); - unsigned oldSize = _renamedFiles.Size(); - unsigned insertIndex = _renamedFiles.AddToUniqueSorted(pair); - if (oldSize == _renamedFiles.Size()) - _renamedFiles[insertIndex].Path = fullProcessedPath; - } - #endif + #endif // ! _WIN32 +} - if (_isSplit) - { - RINOK(_outFileStreamSpec->Seek(_position, STREAM_SEEK_SET, NULL)); - } - - _outFileStream = outStreamLoc2; - } - } - } + +bool CLinkInfo::Parse(const Byte *data, size_t dataSize, bool isLinuxData) +{ + Clear(); + // this->isLinux = isLinuxData; + + if (isLinuxData) + { + isJunction = false; + isHardLink = false; + AString utf; + if (dataSize >= (1 << 12)) + return false; + utf.SetFrom_CalcLen((const char *)data, (unsigned)dataSize); + UString u; + if (!ConvertUTF8ToUnicode(utf, u)) + return false; + linkPath = u; - outStreamLoc = _outFileStream; + // in linux symbolic data: we expect that linux separator '/' is used + // if windows link was created, then we also must use linux separator + if (u.IsEmpty()) + return false; + const wchar_t c = u[0]; + isRelative = !IS_PATH_SEPAR(c); + return true; } + + CReparseAttr reparse; + if (!reparse.Parse(data, dataSize)) + return false; + isHardLink = false; + // isCopyLink = false; + linkPath = reparse.GetPath(); + isJunction = reparse.IsMountPoint(); + + if (reparse.IsSymLink_WSL()) + { + isWSL = true; + isRelative = reparse.IsRelative_WSL(); + } + else + isRelative = reparse.IsRelative_Win(); + + // FIXME !!! + #ifndef _WIN32 + linkPath.Replace(L'\\', WCHAR_PATH_SEPARATOR); + #endif + + return true; } + +#endif // SUPPORT_LINKS - #ifndef _SFX - if (_hashStream) +HRESULT CArchiveExtractCallback::CloseReparseAndFile() +{ + HRESULT res = S_OK; + + #ifdef SUPPORT_LINKS + + size_t reparseSize = 0; + bool repraseMode = false; + bool needSetReparse = false; + CLinkInfo linkInfo; + + if (_bufPtrSeqOutStream) { - if (askExtractMode == NArchive::NExtract::NAskMode::kExtract || - askExtractMode == NArchive::NExtract::NAskMode::kTest) + repraseMode = true; + reparseSize = _bufPtrSeqOutStream_Spec->GetPos(); + if (_curSize_Defined && reparseSize == _outMemBuf.Size()) { - _hashStreamSpec->SetStream(outStreamLoc); - outStreamLoc = _hashStream; - _hashStreamSpec->Init(true); - _hashStreamWasUsed = true; + /* + CReparseAttr reparse; + DWORD errorCode = 0; + needSetReparse = reparse.Parse(_outMemBuf, reparseSize, errorCode); + if (needSetReparse) + { + UString linkPath = reparse.GetPath(); + #ifndef _WIN32 + linkPath.Replace(L'\\', WCHAR_PATH_SEPARATOR); + #endif + } + */ + needSetReparse = linkInfo.Parse(_outMemBuf, reparseSize, _is_SymLink_in_Data_Linux); + if (!needSetReparse) + res = SendMessageError_with_LastError("Incorrect reparse stream", us2fs(_item.Path)); + } + else + { + res = SendMessageError_with_LastError("Unknown reparse stream", us2fs(_item.Path)); } + if (!needSetReparse && _outFileStream) + { + const HRESULT res2 = WriteStream(_outFileStream, _outMemBuf, reparseSize); + if (res == S_OK) + res = res2; + } + _bufPtrSeqOutStream.Release(); } - #endif + #endif // SUPPORT_LINKS - - if (outStreamLoc) + + const HRESULT res2 = CloseFile(); + + if (res == S_OK) + res = res2; + + RINOK(res) + + #ifdef SUPPORT_LINKS + if (repraseMode) { - /* - #ifdef SUPPORT_LINKS + _curSize = reparseSize; + _curSize_Defined = true; - if (!_CopyFile_Path.IsEmpty()) + #ifdef SUPPORT_LINKS + if (needSetReparse) { - RINOK(PrepareOperation(askExtractMode)); - RINOK(MyCopyFile(outStreamLoc)); - return SetOperationResult(NArchive::NExtract::NOperationResult::kOK); + // in Linux : we must delete empty file before symbolic link creation + // in Windows : we can create symbolic link even without file deleting + if (!DeleteFileAlways(_diskFilePath)) + { + RINOK(SendMessageError_with_LastError("can't delete file", _diskFilePath)) + } + { + /* + // for DEBUG ONLY: we can extract sym links as WSL links + // to eliminate (non-admin) errors for sym links. + #ifdef _WIN32 + if (!linkInfo.isHardLink && !linkInfo.isJunction) + linkInfo.isWSL = true; + #endif + */ + bool linkWasSet = false; + RINOK(SetFromLinkPath(_diskFilePath, linkInfo, linkWasSet)) + if (linkWasSet) + _isSymLinkCreated = linkInfo.IsSymLink(); + else + _needSetAttrib = false; + } + /* + if (!NFile::NIO::SetReparseData(_diskFilePath, _item.IsDir, )) + { + res = SendMessageError_with_LastError(kCantCreateSymLink, _diskFilePath); + } + */ } - - if (isCopyLink && _testMode) - return S_OK; - #endif - */ - - *outStream = outStreamLoc.Detach(); } - - return S_OK; - - COM_TRY_END + #endif + return res; } -STDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode) +void CArchiveExtractCallback::SetAttrib() { - COM_TRY_BEGIN + #ifndef _WIN32 + // Linux now doesn't support permissions for symlinks + if (_isSymLinkCreated) + return; + #endif + + if (_itemFailure + || _diskFilePath.IsEmpty() + || _stdOutMode + || !_extractMode) + return; + + #ifndef _WIN32 + if (_fi.Owner.Id_Defined && + _fi.Group.Id_Defined) + { + if (my_chown(_diskFilePath, _fi.Owner.Id, _fi.Group.Id) != 0) + { + SendMessageError_with_LastError("Cannot set owner", _diskFilePath); + } + } + #endif - #ifndef _SFX - if (ExtractToStreamCallback) - return ExtractToStreamCallback->PrepareOperation7(askExtractMode); - #endif - - _extractMode = false; - - switch (askExtractMode) + if (_fi.Attrib_Defined) { - case NArchive::NExtract::NAskMode::kExtract: - if (_testMode) - askExtractMode = NArchive::NExtract::NAskMode::kTest; - else - _extractMode = true; - break; - }; - - return _extractCallback2->PrepareOperation(_item.Path, BoolToInt(_item.IsDir), - askExtractMode, _isSplit ? &_position: 0); - - COM_TRY_END + // const AString s = GetAnsiString(_diskFilePath); + // printf("\nSetFileAttrib_PosixHighDetect: %s: hex:%x\n", s.Ptr(), _fi.Attrib); + bool res = SetFileAttrib_PosixHighDetect(_diskFilePath, _fi.Attrib); + if (!res) + { + // do we need error message here in Windows and in posix? + SendMessageError_with_LastError("Cannot set file attribute", _diskFilePath); + } + } } -STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 opRes) +Z7_COM7F_IMF(CArchiveExtractCallback::SetOperationResult(Int32 opRes)) { COM_TRY_BEGIN - #ifndef _SFX + // printf("\nCArchiveExtractCallback::SetOperationResult: %d %s\n", opRes, GetAnsiString(_diskFilePath)); + + #ifndef Z7_SFX if (ExtractToStreamCallback) - return ExtractToStreamCallback->SetOperationResult7(opRes, BoolToInt(_encrypted)); + { + GetUnpackSize(); + return ExtractToStreamCallback->SetOperationResult8(opRes, BoolToInt(_encrypted), _curSize); + } #endif - #ifndef _SFX + #ifndef Z7_SFX if (_hashStreamWasUsed) { @@ -1447,26 +2321,16 @@ STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 opRes) #endif , _item.Path); _curSize = _hashStreamSpec->GetSize(); - _curSizeDefined = true; + _curSize_Defined = true; _hashStreamSpec->ReleaseStream(); _hashStreamWasUsed = false; } - #endif + #endif // Z7_SFX - if (_outFileStream) - { - _outFileStreamSpec->SetTime( - (WriteCTime && _fi.CTimeDefined) ? &_fi.CTime : NULL, - (WriteATime && _fi.ATimeDefined) ? &_fi.ATime : NULL, - (WriteMTime && _fi.MTimeDefined) ? &_fi.MTime : (_arc->MTimeDefined ? &_arc->MTime : NULL)); - _curSize = _outFileStreamSpec->ProcessedSize; - _curSizeDefined = true; - RINOK(_outFileStreamSpec->Close()); - _outFileStream.Release(); - } + RINOK(CloseReparseAndFile()) - #ifdef _USE_SECURITY_CODE + #ifdef Z7_USE_SECURITY_CODE if (!_stdOutMode && _extractMode && _ntOptions.NtSecurity.Val && _arc->GetRawProps) { const void *data; @@ -1482,16 +2346,16 @@ STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 opRes) SECURITY_INFORMATION securInfo = DACL_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION; if (_saclEnabled) securInfo |= SACL_SECURITY_INFORMATION; - ::SetFileSecurityW(fs2us(_diskFilePath), securInfo, (PSECURITY_DESCRIPTOR)(void *)data); + ::SetFileSecurityW(fs2us(_diskFilePath), securInfo, (PSECURITY_DESCRIPTOR)(void *)(const Byte *)(data)); } } } - #endif + #endif // Z7_USE_SECURITY_CODE - if (!_curSizeDefined) + if (!_curSize_Defined) GetUnpackSize(); - if (_curSizeDefined) + if (_curSize_Defined) { #ifdef SUPPORT_ALT_STREAMS if (_item.IsAltStream) @@ -1510,38 +2374,36 @@ STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 opRes) else NumFiles++; - if (!_stdOutMode && _extractMode && _fi.AttribDefined) - SetFileAttrib(_diskFilePath, _fi.Attrib); + if (_needSetAttrib) + SetAttrib(); - RINOK(_extractCallback2->SetOperationResult(opRes, BoolToInt(_encrypted))); + RINOK(_extractCallback2->SetOperationResult(opRes, BoolToInt(_encrypted))) return S_OK; COM_TRY_END } -STDMETHODIMP CArchiveExtractCallback::ReportExtractResult(UInt32 indexType, UInt32 index, Int32 opRes) + + +Z7_COM7F_IMF(CArchiveExtractCallback::ReportExtractResult(UInt32 indexType, UInt32 index, Int32 opRes)) { if (_folderArchiveExtractCallback2) { bool isEncrypted = false; - wchar_t temp[16]; - UString s2; - const wchar_t *s = NULL; + UString s; if (indexType == NArchive::NEventIndexType::kInArcIndex && index != (UInt32)(Int32)-1) { CReadArcItem item; - RINOK(_arc->GetItem(index, item)); - s2 = item.Path; - s = s2; - RINOK(Archive_GetItemBoolProp(_arc->Archive, index, kpidEncrypted, isEncrypted)); + RINOK(_arc->GetItem(index, item)) + s = item.Path; + RINOK(Archive_GetItemBoolProp(_arc->Archive, index, kpidEncrypted, isEncrypted)) } else { - temp[0] = '#'; - ConvertUInt32ToString(index, temp + 1); - s = temp; + s = '#'; + s.Add_UInt32(index); // if (indexType == NArchive::NEventIndexType::kBlockIndex) {} } @@ -1552,84 +2414,179 @@ STDMETHODIMP CArchiveExtractCallback::ReportExtractResult(UInt32 indexType, UInt } -STDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password) +Z7_COM7F_IMF(CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password)) { COM_TRY_BEGIN if (!_cryptoGetTextPassword) { RINOK(_extractCallback2.QueryInterface(IID_ICryptoGetTextPassword, - &_cryptoGetTextPassword)); + &_cryptoGetTextPassword)) } return _cryptoGetTextPassword->CryptoGetTextPassword(password); COM_TRY_END } -struct CExtrRefSortPair +// ---------- HASH functions ---------- + +FString CArchiveExtractCallback::Hash_GetFullFilePath() { - unsigned Len; - unsigned Index; + // this function changes _item.PathParts. + CorrectPathParts(); + const UStringVector &pathParts = _item.PathParts; + const UString processedPath (MakePathFromParts(pathParts)); + FString fullProcessedPath (us2fs(processedPath)); + if (_pathMode != NExtract::NPathMode::kAbsPaths + || !NName::IsAbsolutePath(processedPath)) + { + fullProcessedPath = MakePath_from_2_Parts( + DirPathPrefix_for_HashFiles, + // _dirPathPrefix, + fullProcessedPath); + } + return fullProcessedPath; +} - int Compare(const CExtrRefSortPair &a) const; -}; -#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; } +Z7_COM7F_IMF(CArchiveExtractCallback::GetDiskProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + if (propID == kpidSize) + { + RINOK(GetItem(index)) + const FString fullProcessedPath = Hash_GetFullFilePath(); + NFile::NFind::CFileInfo fi; + if (fi.Find_FollowLink(fullProcessedPath)) + if (!fi.IsDir()) + prop = (UInt64)fi.Size; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(CArchiveExtractCallback::GetStream2(UInt32 index, ISequentialInStream **inStream, UInt32 mode)) +{ + COM_TRY_BEGIN + *inStream = NULL; + // if (index != _index) return E_FAIL; + if (mode != NUpdateNotifyOp::kHashRead) + return E_FAIL; + + RINOK(GetItem(index)) + const FString fullProcessedPath = Hash_GetFullFilePath(); + + CInFileStream *inStreamSpec = new CInFileStream; + CMyComPtr<ISequentialInStream> inStreamRef = inStreamSpec; + inStreamSpec->Set_PreserveATime(_ntOptions.PreserveATime); + if (!inStreamSpec->OpenShared(fullProcessedPath, _ntOptions.OpenShareForWrite)) + { + RINOK(SendMessageError_with_LastError(kCantOpenInFile, fullProcessedPath)) + return S_OK; + } + *inStream = inStreamRef.Detach(); + return S_OK; + COM_TRY_END +} + -int CExtrRefSortPair::Compare(const CExtrRefSortPair &a) const +Z7_COM7F_IMF(CArchiveExtractCallback::ReportOperation( + UInt32 /* indexType */, UInt32 /* index */, UInt32 /* op */)) { - RINOZ(-MyCompare(Len, a.Len)); - return MyCompare(Index, a.Index); + // COM_TRY_BEGIN + return S_OK; + // COM_TRY_END } -static unsigned GetNumSlashes(const FChar *s) + +// ------------ After Extracting functions ------------ + +void CDirPathSortPair::SetNumSlashes(const FChar *s) { for (unsigned numSlashes = 0;;) { FChar c = *s++; if (c == 0) - return numSlashes; + { + Len = numSlashes; + return; + } if (IS_PATH_SEPAR(c)) numSlashes++; } } + +bool CDirPathTime::SetDirTime() const +{ + return NDir::SetDirTime(Path, + CTime_Defined ? &CTime : NULL, + ATime_Defined ? &ATime : NULL, + MTime_Defined ? &MTime : NULL); +} + + HRESULT CArchiveExtractCallback::SetDirsTimes() { - CRecordVector<CExtrRefSortPair> pairs; - pairs.ClearAndSetSize(_extractedFolderPaths.Size()); + if (!_arc) + return S_OK; + + CRecordVector<CDirPathSortPair> pairs; + pairs.ClearAndSetSize(_extractedFolders.Size()); unsigned i; - for (i = 0; i < _extractedFolderPaths.Size(); i++) + for (i = 0; i < _extractedFolders.Size(); i++) { - CExtrRefSortPair &pair = pairs[i]; + CDirPathSortPair &pair = pairs[i]; pair.Index = i; - pair.Len = GetNumSlashes(_extractedFolderPaths[i]); + pair.SetNumSlashes(_extractedFolders[i].Path); } pairs.Sort2(); + HRESULT res = S_OK; + for (i = 0; i < pairs.Size(); i++) { - int pairIndex = pairs[i].Index; - int index = _extractedFolderIndices[pairIndex]; + const CDirPathTime &dpt = _extractedFolders[pairs[i].Index]; + if (!dpt.SetDirTime()) + { + // result = E_FAIL; + // do we need error message here in Windows and in posix? + // SendMessageError_with_LastError("Cannot set directory time", dpt.Path); + } + } - FILETIME CTime; - FILETIME ATime; - FILETIME MTime; - - bool CTimeDefined; - bool ATimeDefined; - bool MTimeDefined; + /* + #ifndef _WIN32 + for (i = 0; i < _delayedSymLinks.Size(); i++) + { + const CDelayedSymLink &link = _delayedSymLinks[i]; + if (!link.Create()) + { + if (res == S_OK) + res = GetLastError_noZero_HRESULT(); + // res = E_FAIL; + // do we need error message here in Windows and in posix? + SendMessageError_with_LastError("Cannot create Symbolic Link", link._source); + } + } + #endif // _WIN32 + */ - RINOK(GetTime(index, kpidCTime, CTime, CTimeDefined)); - RINOK(GetTime(index, kpidATime, ATime, ATimeDefined)); - RINOK(GetTime(index, kpidMTime, MTime, MTimeDefined)); + ClearExtractedDirsInfo(); + return res; +} - // printf("\n%S", _extractedFolderPaths[pairIndex]); - SetDirTime(_extractedFolderPaths[pairIndex], - (WriteCTime && CTimeDefined) ? &CTime : NULL, - (WriteATime && ATimeDefined) ? &ATime : NULL, - (WriteMTime && MTimeDefined) ? &MTime : (_arc->MTimeDefined ? &_arc->MTime : NULL)); - } - return S_OK; + +HRESULT CArchiveExtractCallback::CloseArc() +{ + HRESULT res = CloseReparseAndFile(); + const HRESULT res2 = SetDirsTimes(); + if (res == S_OK) + res = res2; + _arc = NULL; + return res; } diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveExtractCallback.h b/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveExtractCallback.h index 7d4155fe2e7..5ed20f3f0a8 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveExtractCallback.h +++ b/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveExtractCallback.h @@ -1,15 +1,17 @@ // ArchiveExtractCallback.h -#ifndef __ARCHIVE_EXTRACT_CALLBACK_H -#define __ARCHIVE_EXTRACT_CALLBACK_H +#ifndef ZIP7_INC_ARCHIVE_EXTRACT_CALLBACK_H +#define ZIP7_INC_ARCHIVE_EXTRACT_CALLBACK_H #include "../../../Common/MyCom.h" +#include "../../../Common/MyLinux.h" #include "../../../Common/Wildcard.h" #include "../../IPassword.h" #include "../../Common/FileStreams.h" #include "../../Common/ProgressUtils.h" +#include "../../Common/StreamObjects.h" #include "../../Archive/IArchive.h" @@ -19,20 +21,18 @@ #include "HashCalc.h" -#ifndef _SFX +#ifndef Z7_SFX -class COutStreamWithHash: - public ISequentialOutStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_NOQIB_1( + COutStreamWithHash + , ISequentialOutStream +) CMyComPtr<ISequentialOutStream> _stream; UInt64 _size; bool _calculate; public: IHashCalc *_hash; - MY_UNKNOWN_IMP - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); void SetStream(ISequentialOutStream *stream) { _stream = stream; } void ReleaseStream() { _stream.Release(); } void Init(bool calculate = true) @@ -52,39 +52,56 @@ struct CExtractNtOptions { CBoolPair NtSecurity; CBoolPair SymLinks; + CBoolPair SymLinks_AllowDangerous; CBoolPair HardLinks; CBoolPair AltStreams; bool ReplaceColonForAltStream; bool WriteToAltStreamIfColon; + bool ExtractOwner; + + bool PreAllocateOutFile; + + // used for hash arcs only, when we open external files + bool PreserveATime; + bool OpenShareForWrite; + CExtractNtOptions(): ReplaceColonForAltStream(false), - WriteToAltStreamIfColon(false) + WriteToAltStreamIfColon(false), + ExtractOwner(false), + PreserveATime(false), + OpenShareForWrite(false) { SymLinks.Val = true; + SymLinks_AllowDangerous.Val = false; HardLinks.Val = true; AltStreams.Val = true; + + PreAllocateOutFile = + #ifdef _WIN32 + true; + #else + false; + #endif } }; -#ifndef _SFX +#ifndef Z7_SFX -class CGetProp: - public IGetProp, - public CMyUnknownImp -{ +Z7_CLASS_IMP_COM_1( + CGetProp + , IGetProp +) public: - const CArc *Arc; UInt32 IndexInArc; + const CArc *Arc; // UString Name; // relative path - - MY_UNKNOWN_IMP1(IGetProp) - INTERFACE_IGetProp(;) }; #endif -#ifndef _SFX +#ifndef Z7_SFX #ifndef UNDER_CE #define SUPPORT_LINKS @@ -142,29 +159,160 @@ struct CIndexToPathPair #endif -class CArchiveExtractCallback: + + +struct CFiTimesCAM +{ + CFiTime CTime; + CFiTime ATime; + CFiTime MTime; + + bool CTime_Defined; + bool ATime_Defined; + bool MTime_Defined; + + bool IsSomeTimeDefined() const + { + return + CTime_Defined | + ATime_Defined | + MTime_Defined; + } +}; + +struct CDirPathTime: public CFiTimesCAM +{ + FString Path; + + bool SetDirTime() const; +}; + + +#ifdef SUPPORT_LINKS + +struct CLinkInfo +{ + // bool isCopyLink; + bool isHardLink; + bool isJunction; + bool isRelative; + bool isWSL; + UString linkPath; + + bool IsSymLink() const { return !isHardLink; } + + CLinkInfo(): + // IsCopyLink(false), + isHardLink(false), + isJunction(false), + isRelative(false), + isWSL(false) + {} + + void Clear() + { + // IsCopyLink = false; + isHardLink = false; + isJunction = false; + isRelative = false; + isWSL = false; + linkPath.Empty(); + } + + bool Parse(const Byte *data, size_t dataSize, bool isLinuxData); +}; + +#endif // SUPPORT_LINKS + + +#ifndef _WIN32 + +struct COwnerInfo +{ + bool Id_Defined; + UInt32 Id; + AString Name; + + void Clear() + { + Id_Defined = false; + Id = 0; + Name.Empty(); + } +}; + +#endif + + +class CArchiveExtractCallback Z7_final: public IArchiveExtractCallback, - public IArchiveExtractCallbackMessage, + public IArchiveExtractCallbackMessage2, public ICryptoGetTextPassword, public ICompressProgressInfo, + public IArchiveUpdateCallbackFile, + public IArchiveGetDiskProperty, public CMyUnknownImp { + Z7_COM_UNKNOWN_IMP_5( + /* IArchiveExtractCallback, */ + IArchiveExtractCallbackMessage2, + ICryptoGetTextPassword, + ICompressProgressInfo, + IArchiveUpdateCallbackFile, + IArchiveGetDiskProperty) + + Z7_IFACE_COM7_IMP(IProgress) + Z7_IFACE_COM7_IMP(IArchiveExtractCallback) + Z7_IFACE_COM7_IMP(IArchiveExtractCallbackMessage2) + Z7_IFACE_COM7_IMP(ICryptoGetTextPassword) + Z7_IFACE_COM7_IMP(ICompressProgressInfo) + Z7_IFACE_COM7_IMP(IArchiveUpdateCallbackFile) + Z7_IFACE_COM7_IMP(IArchiveGetDiskProperty) + const CArc *_arc; CExtractNtOptions _ntOptions; + bool _isSplit; + + bool _extractMode; + + bool Write_CTime; + bool Write_ATime; + bool Write_MTime; + bool _keepAndReplaceEmptyDirPrefixes; // replace them to "_"; + + bool _encrypted; + + // bool _is_SymLink_in_Data; + bool _is_SymLink_in_Data_Linux; // false = WIN32, true = LINUX + + bool _needSetAttrib; + bool _isSymLinkCreated; + bool _itemFailure; + + bool _curSize_Defined; + bool _fileLength_WasSet; + + bool _removePartsForAltStreams; + + bool _stdOutMode; + bool _testMode; + bool _multiArchives; + + NExtract::NPathMode::EEnum _pathMode; + NExtract::NOverwriteMode::EEnum _overwriteMode; + const NWildcard::CCensorNode *_wildcardCensor; // we need wildcard for single pass mode (stdin) CMyComPtr<IFolderArchiveExtractCallback> _extractCallback2; - CMyComPtr<ICompressProgressInfo> _compressProgress; - CMyComPtr<ICryptoGetTextPassword> _cryptoGetTextPassword; - CMyComPtr<IArchiveExtractCallbackMessage> _callbackMessage; + // CMyComPtr<ICompressProgressInfo> _compressProgress; + // CMyComPtr<IArchiveExtractCallbackMessage2> _callbackMessage; CMyComPtr<IFolderArchiveExtractCallback2> _folderArchiveExtractCallback2; + CMyComPtr<ICryptoGetTextPassword> _cryptoGetTextPassword; FString _dirPathPrefix; FString _dirPathPrefix_Full; - NExtract::NPathMode::EEnum _pathMode; - NExtract::NOverwriteMode::EEnum _overwriteMode; - #ifndef _SFX + #ifndef Z7_SFX CMyComPtr<IFolderExtractToStreamCallback> ExtractToStreamCallback; CGetProp *GetProp_Spec; @@ -175,54 +323,74 @@ class CArchiveExtractCallback: CReadArcItem _item; FString _diskFilePath; UInt64 _position; - bool _isSplit; - - bool _extractMode; - - bool WriteCTime; - bool WriteATime; - bool WriteMTime; - - bool _encrypted; struct CProcessedFileInfo { - FILETIME CTime; - FILETIME ATime; - FILETIME MTime; + CArcTime CTime; + CArcTime ATime; + CArcTime MTime; UInt32 Attrib; - - bool CTimeDefined; - bool ATimeDefined; - bool MTimeDefined; - bool AttribDefined; + bool Attrib_Defined; + + #ifndef _WIN32 + COwnerInfo Owner; + COwnerInfo Group; + #endif + + bool IsReparse() const + { + return (Attrib_Defined && (Attrib & FILE_ATTRIBUTE_REPARSE_POINT) != 0); + } + + bool IsLinuxSymLink() const + { + return (Attrib_Defined && MY_LIN_S_ISLNK(Attrib >> 16)); + } + + void SetFromPosixAttrib(UInt32 a) + { + // here we set only part of combined attribute required by SetFileAttrib() call + #ifdef _WIN32 + // Windows sets FILE_ATTRIBUTE_NORMAL, if we try to set 0 as attribute. + Attrib = MY_LIN_S_ISDIR(a) ? + FILE_ATTRIBUTE_DIRECTORY : + FILE_ATTRIBUTE_ARCHIVE; + if ((a & 0222) == 0) // (& S_IWUSR) in p7zip + Attrib |= FILE_ATTRIBUTE_READONLY; + // 22.00 : we need type bits for (MY_LIN_S_IFLNK) for IsLinuxSymLink() + a &= MY_LIN_S_IFMT; + if (a == MY_LIN_S_IFLNK) + Attrib |= (a << 16); + #else + Attrib = (a << 16) | FILE_ATTRIBUTE_UNIX_EXTENSION; + #endif + Attrib_Defined = true; + } } _fi; UInt32 _index; UInt64 _curSize; - bool _curSizeDefined; + UInt64 _fileLength_that_WasSet; + COutFileStream *_outFileStreamSpec; CMyComPtr<ISequentialOutStream> _outFileStream; - #ifndef _SFX + CByteBuffer _outMemBuf; + CBufPtrSeqOutStream *_bufPtrSeqOutStream_Spec; + CMyComPtr<ISequentialOutStream> _bufPtrSeqOutStream; + + + #ifndef Z7_SFX COutStreamWithHash *_hashStreamSpec; CMyComPtr<ISequentialOutStream> _hashStream; bool _hashStreamWasUsed; - #endif - - bool _removePartsForAltStreams; - UStringVector _removePathParts; - - #ifndef _SFX bool _use_baseParentFolder_mode; UInt32 _baseParentFolder; - #endif + #endif - bool _stdOutMode; - bool _testMode; - bool _multiArchives; + UStringVector _removePathParts; CMyComPtr<ICompressProgressInfo> _localProgress; UInt64 _packTotal; @@ -230,22 +398,34 @@ class CArchiveExtractCallback: UInt64 _progressTotal; bool _progressTotal_Defined; - FStringVector _extractedFolderPaths; - CRecordVector<UInt32> _extractedFolderIndices; + CObjectVector<CDirPathTime> _extractedFolders; + + #ifndef _WIN32 + // CObjectVector<NWindows::NFile::NDir::CDelayedSymLink> _delayedSymLinks; + #endif - #if defined(_WIN32) && !defined(UNDER_CE) && !defined(_SFX) + #if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX) bool _saclEnabled; #endif void CreateComplexDirectory(const UStringVector &dirPathParts, FString &fullPath); - HRESULT GetTime(int index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined); + HRESULT GetTime(UInt32 index, PROPID propID, CArcTime &ft); HRESULT GetUnpackSize(); + FString Hash_GetFullFilePath(); + + void SetAttrib(); + +public: HRESULT SendMessageError(const char *message, const FString &path); HRESULT SendMessageError_with_LastError(const char *message, const FString &path); - HRESULT SendMessageError2(const char *message, const FString &path1, const FString &path2); + HRESULT SendMessageError2(HRESULT errorCode, const char *message, const FString &path1, const FString &path2); public: + #if defined(_WIN32) && !defined(UNDER_CE) + NExtract::NZoneIdMode::EEnum ZoneMode; + CByteBuffer ZoneBuf; + #endif CLocalProgress *LocalProgressSpec; @@ -255,28 +435,29 @@ public: UInt64 UnpackSize; UInt64 AltStreams_UnpackSize; - MY_UNKNOWN_IMP3(IArchiveExtractCallbackMessage, ICryptoGetTextPassword, ICompressProgressInfo) - - INTERFACE_IArchiveExtractCallback(;) - INTERFACE_IArchiveExtractCallbackMessage(;) - - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); - - STDMETHOD(CryptoGetTextPassword)(BSTR *password); + FString DirPathPrefix_for_HashFiles; CArchiveExtractCallback(); void InitForMulti(bool multiArchives, NExtract::NPathMode::EEnum pathMode, - NExtract::NOverwriteMode::EEnum overwriteMode) + NExtract::NOverwriteMode::EEnum overwriteMode, + NExtract::NZoneIdMode::EEnum zoneMode, + bool keepAndReplaceEmptyDirPrefixes) { _multiArchives = multiArchives; _pathMode = pathMode; _overwriteMode = overwriteMode; + #if defined(_WIN32) && !defined(UNDER_CE) + ZoneMode = zoneMode; + #else + UNUSED_VAR(zoneMode) + #endif + _keepAndReplaceEmptyDirPrefixes = keepAndReplaceEmptyDirPrefixes; NumFolders = NumFiles = NumAltStreams = UnpackSize = AltStreams_UnpackSize = 0; } - #ifndef _SFX + #ifndef Z7_SFX void SetHashMethods(IHashCalc *hash) { @@ -289,6 +470,8 @@ public: #endif + void InitBeforeNewArchive(); + void Init( const CExtractNtOptions &ntOptions, const NWildcard::CCensorNode *wildcardCensor, @@ -304,10 +487,12 @@ public: private: CHardLinks _hardLinks; - UString linkPath; + CLinkInfo _link; - // FString _CopyFile_Path; + // FString _copyFile_Path; // HRESULT MyCopyFile(ISequentialOutStream *outStream); + HRESULT Link(const FString &fullProcessedPath); + HRESULT ReadLink(); public: // call PrepareHardLinks() after Init() @@ -322,7 +507,7 @@ public: // call it after Init() - #ifndef _SFX + #ifndef Z7_SFX void SetBaseParentFolderIndex(UInt32 indexInArc) { _baseParentFolder = indexInArc; @@ -330,9 +515,70 @@ public: } #endif + HRESULT CloseArc(); + +private: + void ClearExtractedDirsInfo() + { + _extractedFolders.Clear(); + #ifndef _WIN32 + // _delayedSymLinks.Clear(); + #endif + } + + HRESULT Read_fi_Props(); + void CorrectPathParts(); + void GetFiTimesCAM(CFiTimesCAM &pt); + void CreateFolders(); + + bool _isRenamed; + HRESULT CheckExistFile(FString &fullProcessedPath, bool &needExit); + HRESULT GetExtractStream(CMyComPtr<ISequentialOutStream> &outStreamLoc, bool &needExit); + HRESULT GetItem(UInt32 index); + + HRESULT CloseFile(); + HRESULT CloseReparseAndFile(); + HRESULT CloseReparseAndFile2(); HRESULT SetDirsTimes(); + + const void *NtReparse_Data; + UInt32 NtReparse_Size; + + #ifdef SUPPORT_LINKS + HRESULT SetFromLinkPath( + const FString &fullProcessedPath, + const CLinkInfo &linkInfo, + bool &linkWasSet); + #endif +}; + + +struct CArchiveExtractCallback_Closer +{ + CArchiveExtractCallback *_ref; + + CArchiveExtractCallback_Closer(CArchiveExtractCallback *ref): _ref(ref) {} + + HRESULT Close() + { + HRESULT res = S_OK; + if (_ref) + { + res = _ref->CloseArc(); + _ref = NULL; + } + return res; + } + + ~CArchiveExtractCallback_Closer() + { + Close(); + } }; + bool CensorNode_CheckPath(const NWildcard::CCensorNode &node, const CReadArcItem &item); +void ReadZoneFile_Of_BaseFile(CFSTR fileName2, CByteBuffer &buf); + #endif diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveName.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveName.cpp index 06d2ab80895..1c0c3a821b1 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveName.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveName.cpp @@ -2,77 +2,175 @@ #include "StdAfx.h" +#include "../../../../C/Sort.h" + +#include "../../../Common/Wildcard.h" +#include "../../../Common/StringToInt.h" + #include "../../../Windows/FileDir.h" #include "../../../Windows/FileName.h" -#include "ExtractingFilePath.h" #include "ArchiveName.h" +#include "ExtractingFilePath.h" using namespace NWindows; using namespace NFile; -UString CreateArchiveName(const NFind::CFileInfo &fi, bool keepName) + +static const char *g_ArcExts = + "7z" + "\0" "zip" + "\0" "tar" + "\0" "wim" + "\0"; + +static const char *g_HashExts = + "sha256" + "\0"; + + +UString CreateArchiveName( + const UStringVector &paths, + bool isHash, + const NFind::CFileInfo *fi, + UString &baseName) { - FString resultName = fi.Name; - if (!fi.IsDir() && !keepName) + bool keepName = isHash; + /* + if (paths.Size() == 1) { - int dotPos = resultName.ReverseFind_Dot(); - if (dotPos > 0) - { - FString archiveName2 = resultName.Left(dotPos); - if (archiveName2.ReverseFind_Dot() < 0) - resultName = archiveName2; - } + const UString &name = paths[0]; + if (name.Len() > 4) + if (CompareFileNames(name.RightPtr(4), L".tar") == 0) + keepName = true; } - return Get_Correct_FsFile_Name(fs2us(resultName)); -} + */ -static FString CreateArchiveName2(const FString &path, bool fromPrev, bool keepName) -{ - FString resultName = FTEXT("Archive"); - if (fromPrev) + UString name ("Archive"); + NFind::CFileInfo fi3; + if (paths.Size() > 1) + fi = NULL; + if (!fi && paths.Size() != 0) { - FString dirPrefix; - if (NDir::GetOnlyDirPrefix(path, dirPrefix)) + const UString &path = paths.Front(); + if (paths.Size() == 1) + { + if (fi3.Find(us2fs(path))) + fi = &fi3; + } + else { - if (!dirPrefix.IsEmpty() && IsPathSepar(dirPrefix.Back())) + // we try to use name of parent folder + FString dirPrefix; + if (NDir::GetOnlyDirPrefix(us2fs(path), dirPrefix)) { - #if defined(_WIN32) && !defined(UNDER_CE) - if (NName::IsDriveRootPath_SuperAllowed(dirPrefix)) - resultName = dirPrefix[dirPrefix.Len() - 3]; // only letter - else - #endif + if (!dirPrefix.IsEmpty() && IsPathSepar(dirPrefix.Back())) { - dirPrefix.DeleteBack(); - NFind::CFileInfo fi; - if (fi.Find(dirPrefix)) - resultName = fi.Name; + #if defined(_WIN32) && !defined(UNDER_CE) + if (NName::IsDriveRootPath_SuperAllowed(dirPrefix)) + { + if (path != fs2us(dirPrefix)) + name = dirPrefix[dirPrefix.Len() - 3]; // only letter + } + else + #endif + { + dirPrefix.DeleteBack(); + if (!dirPrefix.IsEmpty()) + { + const int slash = dirPrefix.ReverseFind_PathSepar(); + if (slash >= 0 && slash != (int)dirPrefix.Len() - 1) + name = dirPrefix.Ptr(slash + 1); + else if (fi3.Find(dirPrefix)) + name = fs2us(fi3.Name); + } + } } } } } - else + + if (fi) { - NFind::CFileInfo fi; - if (fi.Find(path)) + name = fs2us(fi->Name); + if (!fi->IsDir() && !keepName) + { + const int dotPos = name.Find(L'.'); + if (dotPos > 0 && name.Find(L'.', (unsigned)dotPos + 1) < 0) + name.DeleteFrom((unsigned)dotPos); + } + } + name = Get_Correct_FsFile_Name(name); + + CRecordVector<UInt32> ids; + bool simple_IsAllowed = true; + // for (int y = 0; y < 10000; y++) // for debug + { + // ids.Clear(); + UString n; + + FOR_VECTOR (i, paths) { - resultName = fi.Name; - if (!fi.IsDir() && !keepName) + const UString &a = paths[i]; + const int slash = a.ReverseFind_PathSepar(); + // if (name.Len() >= a.Len() - slash + 1) continue; + const wchar_t *s = a.Ptr(slash + 1); + if (!IsPath1PrefixedByPath2(s, name)) + continue; + s += name.Len(); + const char *exts = isHash ? g_HashExts : g_ArcExts; + + for (;;) { - int dotPos = resultName.ReverseFind_Dot(); - if (dotPos > 0) + const char *ext = exts; + const unsigned len = MyStringLen(ext); + if (len == 0) + break; + exts += len + 1; + n = s; + if (n.Len() <= len) + continue; + if (!StringsAreEqualNoCase_Ascii(n.RightPtr(len), ext)) + continue; + n.DeleteFrom(n.Len() - len); + if (n.Back() != '.') + continue; + n.DeleteBack(); + if (n.IsEmpty()) { - FString name2 = resultName.Left(dotPos); - if (name2.ReverseFind_Dot() < 0) - resultName = name2; + simple_IsAllowed = false; + break; } + if (n.Len() < 2) + continue; + if (n[0] != '_') + continue; + const wchar_t *end; + const UInt32 v = ConvertStringToUInt32(n.Ptr(1), &end); + if (*end != 0) + continue; + ids.Add(v); + break; } } } - return resultName; -} -UString CreateArchiveName(const UString &path, bool fromPrev, bool keepName) -{ - return Get_Correct_FsFile_Name(fs2us(CreateArchiveName2(us2fs(path), fromPrev, keepName))); + baseName = name; + if (!simple_IsAllowed) + { + HeapSort(&ids.Front(), ids.Size()); + UInt32 v = 2; + const unsigned num = ids.Size(); + for (unsigned i = 0; i < num; i++) + { + const UInt32 id = ids[i]; + if (id > v) + break; + if (id == v) + v = id + 1; + } + name += '_'; + name.Add_UInt32(v); + } + return name; } diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveName.h b/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveName.h index ec2f1e8d1d9..9b6b7fe9d38 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveName.h +++ b/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveName.h @@ -1,13 +1,16 @@ // ArchiveName.h -#ifndef __ARCHIVE_NAME_H -#define __ARCHIVE_NAME_H - -#include "../../../Common/MyString.h" +#ifndef ZIP7_INC_ARCHIVE_NAME_H +#define ZIP7_INC_ARCHIVE_NAME_H #include "../../../Windows/FileFind.h" -UString CreateArchiveName(const UString &path, bool fromPrev, bool keepName); -UString CreateArchiveName(const NWindows::NFile::NFind::CFileInfo &fileInfo, bool keepName); +/* (fi != NULL) only if (paths.Size() == 1) */ + +UString CreateArchiveName( + const UStringVector &paths, + bool isHash, + const NWindows::NFile::NFind::CFileInfo *fi, + UString &baseName); #endif diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp index fd2807ac149..4e5f1f56041 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp @@ -6,14 +6,54 @@ #include "../../../Windows/FileName.h" #include "../../../Windows/PropVariant.h" +#include "../../../Windows/System.h" -#include "../../Common/FileStreams.h" +#include "../../Common/StreamUtils.h" #include "ArchiveOpenCallback.h" +// #define DEBUG_VOLUMES + +#ifdef DEBUG_VOLUMES +#include <stdio.h> +#endif + + +#ifdef DEBUG_VOLUMES + #define PRF(x) x +#else + #define PRF(x) +#endif + using namespace NWindows; -STDMETHODIMP COpenCallbackImp::SetTotal(const UInt64 *files, const UInt64 *bytes) +HRESULT COpenCallbackImp::Init2(const FString &folderPrefix, const FString &fileName) +{ + Volumes.Init(); + FileNames.Clear(); + FileNames_WasUsed.Clear(); + FileSizes.Clear(); + _subArchiveMode = false; + // TotalSize = 0; + PasswordWasAsked = false; + _folderPrefix = folderPrefix; + if (!_fileInfo.Find_FollowLink(_folderPrefix + fileName)) + { + // throw 20121118; + return GetLastError_noZero_HRESULT(); + } + return S_OK; +} + +Z7_COM7F_IMF(COpenCallbackImp::SetSubArchiveName(const wchar_t *name)) +{ + _subArchiveMode = true; + _subArchiveName = name; + // TotalSize = 0; + return S_OK; +} + +Z7_COM7F_IMF(COpenCallbackImp::SetTotal(const UInt64 *files, const UInt64 *bytes)) { COM_TRY_BEGIN if (ReOpenCallback) @@ -24,7 +64,7 @@ STDMETHODIMP COpenCallbackImp::SetTotal(const UInt64 *files, const UInt64 *bytes COM_TRY_END } -STDMETHODIMP COpenCallbackImp::SetCompleted(const UInt64 *files, const UInt64 *bytes) +Z7_COM7F_IMF(COpenCallbackImp::SetCompleted(const UInt64 *files, const UInt64 *bytes)) { COM_TRY_BEGIN if (ReOpenCallback) @@ -34,8 +74,9 @@ STDMETHODIMP COpenCallbackImp::SetCompleted(const UInt64 *files, const UInt64 *b return Callback->Open_SetCompleted(files, bytes); COM_TRY_END } - -STDMETHODIMP COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value) + + +Z7_COM7F_IMF(COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -48,37 +89,194 @@ STDMETHODIMP COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value) else switch (propID) { - case kpidName: prop = _fileInfo.Name; break; + case kpidName: prop = fs2us(_fileInfo.Name); break; case kpidIsDir: prop = _fileInfo.IsDir(); break; case kpidSize: prop = _fileInfo.Size; break; - case kpidAttrib: prop = (UInt32)_fileInfo.Attrib; break; - case kpidCTime: prop = _fileInfo.CTime; break; - case kpidATime: prop = _fileInfo.ATime; break; - case kpidMTime: prop = _fileInfo.MTime; break; + case kpidAttrib: prop = (UInt32)_fileInfo.GetWinAttrib(); break; + case kpidPosixAttrib: prop = (UInt32)_fileInfo.GetPosixAttrib(); break; + case kpidCTime: PropVariant_SetFrom_FiTime(prop, _fileInfo.CTime); break; + case kpidATime: PropVariant_SetFrom_FiTime(prop, _fileInfo.ATime); break; + case kpidMTime: PropVariant_SetFrom_FiTime(prop, _fileInfo.MTime); break; } prop.Detach(value); return S_OK; COM_TRY_END } -struct CInFileStreamVol: public CInFileStream -{ - int FileNameIndex; + +// ---------- CInFileStreamVol ---------- + +Z7_CLASS_IMP_COM_2( + CInFileStreamVol + , IInStream + , IStreamGetSize +) + Z7_IFACE_COM7_IMP(ISequentialInStream) +public: + unsigned FileIndex; COpenCallbackImp *OpenCallbackImp; CMyComPtr<IArchiveOpenCallback> OpenCallbackRef; - + + HRESULT EnsureOpen() + { + return OpenCallbackImp->Volumes.EnsureOpen(FileIndex); + } + ~CInFileStreamVol() { if (OpenCallbackRef) - OpenCallbackImp->FileNames_WasUsed[FileNameIndex] = false; + OpenCallbackImp->AtCloseFile(FileIndex); } }; +void CMultiStreams::InsertToList(unsigned index) +{ + { + CSubStream &s = Streams[index]; + s.Next = Head; + s.Prev = -1; + } + if (Head != -1) + Streams[(unsigned)Head].Prev = (int)index; + else + { + // if (Tail != -1) throw 1; + Tail = (int)index; + } + Head = (int)index; + NumListItems++; +} + +// s must bee in List +void CMultiStreams::RemoveFromList(CSubStream &s) +{ + if (s.Next != -1) Streams[(unsigned)s.Next].Prev = s.Prev; else Tail = s.Prev; + if (s.Prev != -1) Streams[(unsigned)s.Prev].Next = s.Next; else Head = s.Next; + s.Next = -1; // optional + s.Prev = -1; // optional + NumListItems--; +} + +void CMultiStreams::CloseFile(unsigned index) +{ + CSubStream &s = Streams[index]; + if (s.Stream) + { + s.Stream.Release(); + RemoveFromList(s); + // s.InFile->Close(); + // s.IsOpen = false; + #ifdef DEBUG_VOLUMES + static int numClosing = 0; + numClosing++; + printf("\nCloseFile %u, total_closes = %u, num_open_files = %u\n", index, numClosing, NumListItems); + #endif + } +} + +void CMultiStreams::Init() +{ + Head = -1; + Tail = -1; + NumListItems = 0; + Streams.Clear(); +} + +CMultiStreams::CMultiStreams(): + Head(-1), + Tail(-1), + NumListItems(0) +{ + NumOpenFiles_AllowedMax = NSystem::Get_File_OPEN_MAX_Reduced_for_3_tasks(); + PRF(printf("\nNumOpenFiles_Limit = %u\n", NumOpenFiles_AllowedMax)); +} + + +HRESULT CMultiStreams::PrepareToOpenNew() +{ + if (NumListItems < NumOpenFiles_AllowedMax) + return S_OK; + if (Tail == -1) + return E_FAIL; + CMultiStreams::CSubStream &tailStream = Streams[(unsigned)Tail]; + RINOK(InStream_GetPos(tailStream.Stream, tailStream.LocalPos)) + CloseFile((unsigned)Tail); + return S_OK; +} + + +HRESULT CMultiStreams::EnsureOpen(unsigned index) +{ + CMultiStreams::CSubStream &s = Streams[index]; + if (s.Stream) + { + if ((int)index != Head) + { + RemoveFromList(s); + InsertToList(index); + } + } + else + { + RINOK(PrepareToOpenNew()) + { + CInFileStream *inFile = new CInFileStream; + CMyComPtr<IInStream> inStreamTemp = inFile; + if (!inFile->Open(s.Path)) + return GetLastError_noZero_HRESULT(); + s.FileSpec = inFile; + s.Stream = s.FileSpec; + InsertToList(index); + } + // s.IsOpen = true; + if (s.LocalPos != 0) + { + RINOK(s.Stream->Seek((Int64)s.LocalPos, STREAM_SEEK_SET, &s.LocalPos)) + } + #ifdef DEBUG_VOLUMES + static int numOpens = 0; + numOpens++; + printf("\n-- %u, ReOpen, total_reopens = %u, num_open_files = %u\n", index, numOpens, NumListItems); + #endif + } + return S_OK; +} + + +Z7_COM7F_IMF(CInFileStreamVol::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + if (processedSize) + *processedSize = 0; + if (size == 0) + return S_OK; + RINOK(EnsureOpen()) + CMultiStreams::CSubStream &s = OpenCallbackImp->Volumes.Streams[FileIndex]; + PRF(printf("\n== %u, Read =%u \n", FileIndex, size)); + return s.Stream->Read(data, size, processedSize); +} + +Z7_COM7F_IMF(CInFileStreamVol::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) +{ + // if (seekOrigin >= 3) return STG_E_INVALIDFUNCTION; + RINOK(EnsureOpen()) + CMultiStreams::CSubStream &s = OpenCallbackImp->Volumes.Streams[FileIndex]; + PRF(printf("\n-- %u, Seek seekOrigin=%u Seek =%u\n", FileIndex, seekOrigin, (unsigned)offset)); + return s.Stream->Seek(offset, seekOrigin, newPosition); +} + +Z7_COM7F_IMF(CInFileStreamVol::GetSize(UInt64 *size)) +{ + RINOK(EnsureOpen()) + CMultiStreams::CSubStream &s = OpenCallbackImp->Volumes.Streams[FileIndex]; + return s.FileSpec->GetSize(size); +} + + // from ArchiveExtractCallback.cpp bool IsSafePath(const UString &path); -STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name, IInStream **inStream) +Z7_COM7F_IMF(COpenCallbackImp::GetStream(const wchar_t *name, IInStream **inStream)) { COM_TRY_BEGIN *inStream = NULL; @@ -87,13 +285,13 @@ STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name, IInStream **inStre return S_FALSE; if (Callback) { - RINOK(Callback->Open_CheckBreak()); + RINOK(Callback->Open_CheckBreak()) } UString name2 = name; - #ifndef _SFX + #ifndef Z7_SFX #ifdef _WIN32 name2.Replace(L'/', WCHAR_PATH_SEPARATOR); @@ -102,30 +300,58 @@ STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name, IInStream **inStre // if (!allowAbsVolPaths) if (!IsSafePath(name2)) return S_FALSE; - + + #ifdef _WIN32 + /* WIN32 allows wildcards in Find() function + and doesn't allow wildcard in File.Open() + so we can work without the following wildcard check here */ + if (name2.Find(L'*') >= 0) + return S_FALSE; + { + unsigned startPos = 0; + if (name2.IsPrefixedBy_Ascii_NoCase("\\\\?\\")) + startPos = 3; + if (name2.Find(L'?', startPos) >= 0) + return S_FALSE; + } + #endif + #endif FString fullPath; if (!NFile::NName::GetFullPath(_folderPrefix, us2fs(name2), fullPath)) return S_FALSE; - if (!_fileInfo.Find(fullPath)) + if (!_fileInfo.Find_FollowLink(fullPath)) return S_FALSE; if (_fileInfo.IsDir()) return S_FALSE; - CInFileStreamVol *inFile = new CInFileStreamVol; - CMyComPtr<IInStream> inStreamTemp = inFile; - if (!inFile->Open(fullPath)) + + CMultiStreams::CSubStream s; + { - DWORD lastError = ::GetLastError(); - if (lastError == 0) - return E_FAIL; - return HRESULT_FROM_WIN32(lastError); + CInFileStream *inFile = new CInFileStream; + CMyComPtr<IInStream> inStreamTemp = inFile; + if (!inFile->Open(fullPath)) + return GetLastError_noZero_HRESULT(); + RINOK(Volumes.PrepareToOpenNew()) + s.FileSpec = inFile; + s.Stream = s.FileSpec; + s.Path = fullPath; + // s.Size = _fileInfo.Size; + // s.IsOpen = true; } + const unsigned fileIndex = Volumes.Streams.Add(s); + Volumes.InsertToList(fileIndex); + FileSizes.Add(_fileInfo.Size); FileNames.Add(name2); - inFile->FileNameIndex = FileNames_WasUsed.Add(true); + FileNames_WasUsed.Add(true); + + CInFileStreamVol *inFile = new CInFileStreamVol; + CMyComPtr<IInStream> inStreamTemp = inFile; + inFile->FileIndex = fileIndex; inFile->OpenCallbackImp = this; inFile->OpenCallbackRef = this; // TotalSize += _fileInfo.Size; @@ -134,14 +360,16 @@ STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name, IInStream **inStre COM_TRY_END } -#ifndef _NO_CRYPTO -STDMETHODIMP COpenCallbackImp::CryptoGetTextPassword(BSTR *password) + +#ifndef Z7_NO_CRYPTO +Z7_COM7F_IMF(COpenCallbackImp::CryptoGetTextPassword(BSTR *password)) { COM_TRY_BEGIN if (ReOpenCallback) { - CMyComPtr<ICryptoGetTextPassword> getTextPassword; - ReOpenCallback.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword); + Z7_DECL_CMyComPtr_QI_FROM( + ICryptoGetTextPassword, + getTextPassword, ReOpenCallback) if (getTextPassword) return getTextPassword->CryptoGetTextPassword(password); } @@ -152,3 +380,14 @@ STDMETHODIMP COpenCallbackImp::CryptoGetTextPassword(BSTR *password) COM_TRY_END } #endif + +// IProgress +Z7_COM7F_IMF(COpenCallbackImp::SetTotal(const UInt64 /* total */)) +{ + return S_OK; +} + +Z7_COM7F_IMF(COpenCallbackImp::SetCompleted(const UInt64 * /* completed */)) +{ + return S_OK; +} diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveOpenCallback.h b/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveOpenCallback.h index e9575f56123..4e44c9dde21 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveOpenCallback.h +++ b/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveOpenCallback.h @@ -1,111 +1,180 @@ // ArchiveOpenCallback.h -#ifndef __ARCHIVE_OPEN_CALLBACK_H -#define __ARCHIVE_OPEN_CALLBACK_H +#ifndef ZIP7_INC_ARCHIVE_OPEN_CALLBACK_H +#define ZIP7_INC_ARCHIVE_OPEN_CALLBACK_H #include "../../../Common/MyCom.h" #include "../../../Windows/FileFind.h" -#ifndef _NO_CRYPTO +#include "../../Common/FileStreams.h" + +#ifndef Z7_NO_CRYPTO #include "../../IPassword.h" #endif #include "../../Archive/IArchive.h" -#ifdef _NO_CRYPTO +Z7_PURE_INTERFACES_BEGIN + +#ifdef Z7_NO_CRYPTO -#define INTERFACE_IOpenCallbackUI_Crypto(x) +#define Z7_IFACEM_IOpenCallbackUI_Crypto(x) #else -#define INTERFACE_IOpenCallbackUI_Crypto(x) \ - virtual HRESULT Open_CryptoGetTextPassword(BSTR *password) x; \ - /* virtual HRESULT Open_GetPasswordIfAny(bool &passwordIsDefined, UString &password) x; */ \ - /* virtual bool Open_WasPasswordAsked() x; */ \ - /* virtual void Open_Clear_PasswordWasAsked_Flag() x; */ \ +#define Z7_IFACEM_IOpenCallbackUI_Crypto(x) \ + virtual HRESULT Open_CryptoGetTextPassword(BSTR *password) x \ + /* virtual HRESULT Open_GetPasswordIfAny(bool &passwordIsDefined, UString &password) x */ \ + /* virtual bool Open_WasPasswordAsked() x */ \ + /* virtual void Open_Clear_PasswordWasAsked_Flag() x */ \ #endif -#define INTERFACE_IOpenCallbackUI(x) \ - virtual HRESULT Open_CheckBreak() x; \ - virtual HRESULT Open_SetTotal(const UInt64 *files, const UInt64 *bytes) x; \ - virtual HRESULT Open_SetCompleted(const UInt64 *files, const UInt64 *bytes) x; \ - virtual HRESULT Open_Finished() x; \ - INTERFACE_IOpenCallbackUI_Crypto(x) +#define Z7_IFACEN_IOpenCallbackUI(x) \ + virtual HRESULT Open_CheckBreak() x \ + virtual HRESULT Open_SetTotal(const UInt64 *files, const UInt64 *bytes) x \ + virtual HRESULT Open_SetCompleted(const UInt64 *files, const UInt64 *bytes) x \ + virtual HRESULT Open_Finished() x \ + Z7_IFACEM_IOpenCallbackUI_Crypto(x) + +Z7_IFACE_DECL_PURE(IOpenCallbackUI) + +Z7_PURE_INTERFACES_END + -struct IOpenCallbackUI +class CMultiStreams Z7_final { - INTERFACE_IOpenCallbackUI(=0) +public: + struct CSubStream + { + CMyComPtr<IInStream> Stream; + CInFileStream *FileSpec; + FString Path; + // UInt64 Size; + UInt64 LocalPos; + int Next; // next older + int Prev; // prev newer + // bool IsOpen; + + CSubStream(): + FileSpec(NULL), + // Size(0), + LocalPos(0), + Next(-1), + Prev(-1) + // IsOpen(false) + {} + }; + + CObjectVector<CSubStream> Streams; +private: + // we must use critical section here, if we want to access from different volumnes simultaneously + int Head; // newest + int Tail; // oldest + unsigned NumListItems; + unsigned NumOpenFiles_AllowedMax; +public: + + CMultiStreams(); + void Init(); + HRESULT PrepareToOpenNew(); + void InsertToList(unsigned index); + void RemoveFromList(CSubStream &s); + void CloseFile(unsigned index); + HRESULT EnsureOpen(unsigned index); }; -class COpenCallbackImp: + +/* + We need COpenCallbackImp class for multivolume processing. + Also we use it as proxy from COM interfaces (IArchiveOpenCallback) to internal (IOpenCallbackUI) interfaces. + If archive is multivolume: + COpenCallbackImp object will exist after Open stage. + COpenCallbackImp object will be deleted when last reference + from each volume object (CInFileStreamVol) will be closed (when archive will be closed). +*/ + +class COpenCallbackImp Z7_final: public IArchiveOpenCallback, public IArchiveOpenVolumeCallback, public IArchiveOpenSetSubArchiveName, - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO public ICryptoGetTextPassword, - #endif + #endif + public IProgress, // IProgress is used for 7zFM public CMyUnknownImp { + Z7_COM_QI_BEGIN2(IArchiveOpenCallback) + Z7_COM_QI_ENTRY(IArchiveOpenVolumeCallback) + Z7_COM_QI_ENTRY(IArchiveOpenSetSubArchiveName) + #ifndef Z7_NO_CRYPTO + Z7_COM_QI_ENTRY(ICryptoGetTextPassword) + #endif + // Z7_COM_QI_ENTRY(IProgress) // the code doesn't require it + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(IArchiveOpenCallback) + Z7_IFACE_COM7_IMP(IArchiveOpenVolumeCallback) + Z7_IFACE_COM7_IMP(IProgress) public: - MY_QUERYINTERFACE_BEGIN2(IArchiveOpenVolumeCallback) - MY_QUERYINTERFACE_ENTRY(IArchiveOpenSetSubArchiveName) - #ifndef _NO_CRYPTO - MY_QUERYINTERFACE_ENTRY(ICryptoGetTextPassword) - #endif - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - INTERFACE_IArchiveOpenCallback(;) - INTERFACE_IArchiveOpenVolumeCallback(;) - - #ifndef _NO_CRYPTO - STDMETHOD(CryptoGetTextPassword)(BSTR *password); - #endif - - STDMETHOD(SetSubArchiveName(const wchar_t *name)) - { - _subArchiveMode = true; - _subArchiveName = name; - // TotalSize = 0; - return S_OK; - } - + Z7_IFACE_COM7_IMP(IArchiveOpenSetSubArchiveName) private: - FString _folderPrefix; - NWindows::NFile::NFind::CFileInfo _fileInfo; + #ifndef Z7_NO_CRYPTO + Z7_IFACE_COM7_IMP(ICryptoGetTextPassword) + #endif + bool _subArchiveMode; - UString _subArchiveName; public: + bool PasswordWasAsked; UStringVector FileNames; CBoolVector FileNames_WasUsed; CRecordVector<UInt64> FileSizes; - - bool PasswordWasAsked; + void AtCloseFile(unsigned fileIndex) + { + FileNames_WasUsed[fileIndex] = false; + Volumes.CloseFile(fileIndex); + } + + /* we have two ways to Callback from this object + 1) IArchiveOpenCallback * ReOpenCallback - for ReOpen function, when IOpenCallbackUI is not available + 2) IOpenCallbackUI *Callback - for usual callback + we can't transfer IOpenCallbackUI pointer via internal interface, + so we use ReOpenCallback to callback without IOpenCallbackUI. + */ + + /* we use Callback/ReOpenCallback only at Open stage. + So the CMyComPtr reference counter is not required, + and we don't want additional reference to unused object, + if COpenCallbackImp is not closed + */ + IArchiveOpenCallback *ReOpenCallback; + // CMyComPtr<IArchiveOpenCallback> ReOpenCallback; IOpenCallbackUI *Callback; - CMyComPtr<IArchiveOpenCallback> ReOpenCallback; + // CMyComPtr<IUnknown> Callback_Ref; + +private: + FString _folderPrefix; + UString _subArchiveName; + NWindows::NFile::NFind::CFileInfo _fileInfo; + +public: + CMultiStreams Volumes; + // UInt64 TotalSize; - COpenCallbackImp(): Callback(NULL), _subArchiveMode(false) {} + COpenCallbackImp(): + _subArchiveMode(false), + ReOpenCallback(NULL), + Callback(NULL) {} - void Init(const FString &folderPrefix, const FString &fileName) - { - _folderPrefix = folderPrefix; - if (!_fileInfo.Find(_folderPrefix + fileName)) - throw 20121118; - FileNames.Clear(); - FileNames_WasUsed.Clear(); - FileSizes.Clear(); - _subArchiveMode = false; - // TotalSize = 0; - PasswordWasAsked = false; - } + HRESULT Init2(const FString &folderPrefix, const FString &fileName); bool SetSecondFileInfo(CFSTR newName) { - return _fileInfo.Find(newName) && !_fileInfo.IsDir(); + return _fileInfo.Find_FollowLink(newName) && !_fileInfo.IsDir(); } }; diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/Bench.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/Bench.cpp index ecbacbc9c8e..5da9783d4e1 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/Bench.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Common/Bench.cpp @@ -2,19 +2,24 @@ #include "StdAfx.h" -#include <stdio.h> +#include "../../../../C/CpuArch.h" + +// #include <stdio.h> #ifndef _WIN32 + #define USE_POSIX_TIME #define USE_POSIX_TIME2 -#endif +#endif // _WIN32 #ifdef USE_POSIX_TIME #include <time.h> +#include <unistd.h> #ifdef USE_POSIX_TIME2 #include <sys/time.h> +#include <sys/times.h> #endif -#endif +#endif // USE_POSIX_TIME #ifdef _WIN32 #define USE_ALLOCA @@ -29,37 +34,34 @@ #endif #include "../../../../C/7zCrc.h" -#include "../../../../C/Alloc.h" -#include "../../../../C/CpuArch.h" - -#include "../../../Windows/System.h" +#include "../../../../C/RotateDefs.h" -#ifndef _7ZIP_ST +#ifndef Z7_ST #include "../../../Windows/Synchronization.h" #include "../../../Windows/Thread.h" #endif -#if defined(_WIN32) || defined(UNIX_USE_WIN_FILE) -#define USE_WIN_FILE -#endif - -#ifdef USE_WIN_FILE +#include "../../../Windows/FileFind.h" #include "../../../Windows/FileIO.h" -#endif - +#include "../../../Windows/SystemInfo.h" +#include "../../../Common/MyBuffer2.h" #include "../../../Common/IntToString.h" #include "../../../Common/StringConvert.h" #include "../../../Common/StringToInt.h" +#include "../../../Common/Wildcard.h" #include "../../Common/MethodProps.h" +#include "../../Common/StreamObjects.h" #include "../../Common/StreamUtils.h" #include "Bench.h" using namespace NWindows; +#ifndef Z7_ST static const UInt32 k_LZMA = 0x030101; +#endif static const UInt64 kComplexInCommands = (UInt64)1 << #ifdef UNDER_CE @@ -68,9 +70,9 @@ static const UInt64 kComplexInCommands = (UInt64)1 << 34; #endif -static const UInt32 kComplexInSeconds = 4; +static const UInt32 kComplexInMs = 4000; -static void SetComplexCommands(UInt32 complexInSeconds, +static void SetComplexCommandsMs(UInt32 complexInMs, bool isSpecifiedFreq, UInt64 cpuFreq, UInt64 &complexInCommands) { complexInCommands = kComplexInCommands; @@ -80,96 +82,80 @@ static void SetComplexCommands(UInt32 complexInSeconds, cpuFreq = kMinFreq; if (cpuFreq < kMaxFreq || isSpecifiedFreq) { - if (complexInSeconds != 0) - complexInCommands = complexInSeconds * cpuFreq; + if (complexInMs != 0) + complexInCommands = complexInMs * cpuFreq / 1000; else complexInCommands = cpuFreq >> 2; } } +// const UInt64 kBenchmarkUsageMult = 1000000; // for debug +static const unsigned kBenchmarkUsageMultBits = 16; +static const UInt64 kBenchmarkUsageMult = 1 << kBenchmarkUsageMultBits; + +UInt64 Benchmark_GetUsage_Percents(UInt64 usage) +{ + return (100 * usage + kBenchmarkUsageMult / 2) / kBenchmarkUsageMult; +} + static const unsigned kNumHashDictBits = 17; -static const UInt32 kFilterUnpackSize = (48 << 10); +static const UInt32 kFilterUnpackSize = (47 << 10); // + 5; // for test -static const unsigned kOldLzmaDictBits = 30; +static const unsigned kOldLzmaDictBits = 32; -static const UInt32 kAdditionalSize = (1 << 16); +// static const size_t kAdditionalSize = (size_t)1 << 32; // for debug +static const size_t kAdditionalSize = (size_t)1 << 16; static const UInt32 kCompressedAdditionalSize = (1 << 10); -static const UInt32 kMaxLzmaPropSize = 5; + +static const UInt32 kMaxMethodPropSize = (1 << 6); + + +#define ALLOC_WITH_HRESULT(_buffer_, _size_) \ + { (_buffer_)->Alloc(_size_); \ + if (_size_ && !(_buffer_)->IsAllocated()) return E_OUTOFMEMORY; } + class CBaseRandomGenerator { UInt32 A1; UInt32 A2; + UInt32 Salt; public: - CBaseRandomGenerator() { Init(); } + CBaseRandomGenerator(UInt32 salt = 0): Salt(salt) { Init(); } void Init() { A1 = 362436069; A2 = 521288629;} + Z7_FORCE_INLINE UInt32 GetRnd() { - return + return Salt ^ + ( ((A1 = 36969 * (A1 & 0xffff) + (A1 >> 16)) << 16) + - ((A2 = 18000 * (A2 & 0xffff) + (A2 >> 16)) ); + ((A2 = 18000 * (A2 & 0xffff) + (A2 >> 16)) ) + ); } }; -static const unsigned kBufferAlignment = 1 << 4; - -struct CBenchBuffer +Z7_NO_INLINE +static void RandGen(Byte *buf, size_t size) { - size_t BufferSize; - - #ifdef _WIN32 - - Byte *Buffer; - - CBenchBuffer(): BufferSize(0), Buffer(NULL) {} - ~CBenchBuffer() { ::MidFree(Buffer); } - - void AllocAlignedMask(size_t size, size_t) - { - ::MidFree(Buffer); - BufferSize = 0; - Buffer = (Byte *)::MidAlloc(size); - if (Buffer) - BufferSize = size; - } - - #else - - Byte *Buffer; - Byte *_bufBase; - - CBenchBuffer(): BufferSize(0), Buffer(NULL), _bufBase(NULL){} - ~CBenchBuffer() { ::MidFree(_bufBase); } - - void AllocAlignedMask(size_t size, size_t alignMask) + CBaseRandomGenerator RG; + const size_t size4 = size & ~((size_t)3); + size_t i; + for (i = 0; i < size4; i += 4) { - ::MidFree(_bufBase); - Buffer = NULL; - BufferSize = 0; - _bufBase = (Byte *)::MidAlloc(size + alignMask); - - if (_bufBase) - { - // Buffer = (Byte *)(((uintptr_t)_bufBase + alignMask) & ~(uintptr_t)alignMask); - Buffer = (Byte *)(((ptrdiff_t)_bufBase + alignMask) & ~(ptrdiff_t)alignMask); - BufferSize = size; - } + const UInt32 v = RG.GetRnd(); + SetUi32(buf + i, v) } - - #endif - - bool Alloc(size_t size) + UInt32 v = RG.GetRnd(); + for (; i < size; i++) { - if (Buffer && BufferSize == size) - return true; - AllocAlignedMask(size, kBufferAlignment - 1); - return (Buffer != NULL || size == 0); + buf[i] = (Byte)v; + v >>= 8; } -}; +} -class CBenchRandomGenerator: public CBenchBuffer +class CBenchRandomGenerator: public CMidAlignedBuffer { static UInt32 GetVal(UInt32 &res, unsigned numBits) { @@ -186,27 +172,33 @@ class CBenchRandomGenerator: public CBenchBuffer public: - void GenerateSimpleRandom(CBaseRandomGenerator *_RG_) + void GenerateSimpleRandom(UInt32 salt) { - CBaseRandomGenerator rg = *_RG_; - const size_t bufSize = BufferSize; - Byte *buf = Buffer; + CBaseRandomGenerator rg(salt); + const size_t bufSize = Size(); + Byte *buf = (Byte *)*this; for (size_t i = 0; i < bufSize; i++) buf[i] = (Byte)rg.GetRnd(); - *_RG_ = rg; } - void GenerateLz(unsigned dictBits, CBaseRandomGenerator *_RG_) + void GenerateLz(unsigned dictBits, UInt32 salt) { - CBaseRandomGenerator rg = *_RG_; - UInt32 pos = 0; - UInt32 rep0 = 1; - const size_t bufSize = BufferSize; - Byte *buf = Buffer; + CBaseRandomGenerator rg(salt); + size_t pos = 0; + size_t rep0 = 1; + const size_t bufSize = Size(); + Byte *buf = (Byte *)*this; unsigned posBits = 1; + + // printf("\n dictBits = %d\n", (UInt32)dictBits); + // printf("\n bufSize = 0x%p\n", (const void *)bufSize); while (pos < bufSize) { + /* + if (pos >= ((UInt32)1 << 31)) + printf(" %x\n", pos); + */ UInt32 r = rg.GetRnd(); if (GetVal(r, 1) == 0 || pos < 1024) buf[pos++] = (Byte)(r & 0xFF); @@ -219,7 +211,7 @@ public: { len += GetLen(r); - while (((UInt32)1 << posBits) < pos) + while (((size_t)1 << posBits) < pos) posBits++; unsigned numBitsMax = dictBits; @@ -233,11 +225,12 @@ public: for (;;) { - UInt32 ppp = GetVal(r, numLogBits) + kAddBits; + const UInt32 ppp = GetVal(r, numLogBits) + kAddBits; r = rg.GetRnd(); if (ppp > numBitsMax) continue; - rep0 = GetVal(r, ppp); + // rep0 = GetVal(r, ppp); + rep0 = r & (((size_t)1 << ppp) - 1); if (rep0 < pos) break; r = rg.GetRnd(); @@ -245,10 +238,11 @@ public: rep0++; } + // len *= 300; // for debug { - UInt32 rem = (UInt32)bufSize - pos; + const size_t rem = bufSize - pos; if (len > rem) - len = rem; + len = (UInt32)rem; } Byte *dest = buf + pos; const Byte *src = dest - rep0; @@ -257,51 +251,54 @@ public: *dest++ = *src++; } } - - *_RG_ = rg; + // printf("\n CRC = %x\n", CrcCalc(buf, bufSize)); } }; -class CBenchmarkInStream: - public ISequentialInStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_NOQIB_1( + CBenchmarkInStream + , ISequentialInStream +) const Byte *Data; size_t Pos; size_t Size; public: - MY_UNKNOWN_IMP void Init(const Byte *data, size_t size) { Data = data; Size = size; Pos = 0; } - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + bool WasFinished() const { return Pos == Size; } }; -STDMETHODIMP CBenchmarkInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CBenchmarkInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) { - size_t remain = Size - Pos; - UInt32 kMaxBlockSize = (1 << 20); + const UInt32 kMaxBlockSize = (1 << 20); if (size > kMaxBlockSize) size = kMaxBlockSize; + const size_t remain = Size - Pos; if (size > remain) size = (UInt32)remain; - for (UInt32 i = 0; i < size; i++) - ((Byte *)data)[i] = Data[Pos + i]; + + if (size != 0) + memcpy(data, Data + Pos, size); + Pos += size; if (processedSize) *processedSize = size; return S_OK; } -class CBenchmarkOutStream: + +class CBenchmarkOutStream Z7_final: public ISequentialOutStream, - public CBenchBuffer, - public CMyUnknownImp + public CMyUnknownImp, + public CMidAlignedBuffer { + Z7_COM_UNKNOWN_IMP_0 + Z7_IFACE_COM7_IMP(ISequentialOutStream) // bool _overflow; public: size_t Pos; @@ -319,23 +316,32 @@ public: Pos = 0; } - // void Print() { printf("\n%8d %8d\n", (unsigned)BufferSize, (unsigned)Pos); } + void InitCrc() + { + Crc = CRC_INIT_VAL; + } - MY_UNKNOWN_IMP - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + void Calc(const void *data, size_t size) + { + Crc = CrcUpdate(Crc, data, size); + } + + size_t GetPos() const { return Pos; } + + // void Print() { printf("\n%8d %8d\n", (unsigned)BufferSize, (unsigned)Pos); } }; -STDMETHODIMP CBenchmarkOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CBenchmarkOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { - size_t curSize = BufferSize - Pos; + size_t curSize = Size() - Pos; if (curSize > size) curSize = size; if (curSize != 0) { if (RealCopy) - memcpy(Buffer + Pos, data, curSize); + memcpy(((Byte *)*this) + Pos, data, curSize); if (CalcCrc) - Crc = CrcUpdate(Crc, data, curSize); + Calc(data, curSize); Pos += curSize; } if (processedSize) @@ -348,46 +354,51 @@ STDMETHODIMP CBenchmarkOutStream::Write(const void *data, UInt32 size, UInt32 *p return S_OK; } -class CCrcOutStream: - public ISequentialOutStream, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_NOQIB_1( + CCrcOutStream + , ISequentialOutStream +) public: bool CalcCrc; UInt32 Crc; - MY_UNKNOWN_IMP - - CCrcOutStream(): CalcCrc(true) {}; - void Init() { Crc = CRC_INIT_VAL; } - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + UInt64 Pos; + + CCrcOutStream(): CalcCrc(true) {} + void Init() { Crc = CRC_INIT_VAL; Pos = 0; } + void Calc(const void *data, size_t size) + { + Crc = CrcUpdate(Crc, data, size); + } }; -STDMETHODIMP CCrcOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CCrcOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) { if (CalcCrc) - Crc = CrcUpdate(Crc, data, size); + Calc(data, size); + Pos += size; if (processedSize) *processedSize = size; return S_OK; } +// #include "../../../../C/My_sys_time.h" + static UInt64 GetTimeCount() { #ifdef USE_POSIX_TIME #ifdef USE_POSIX_TIME2 timeval v; - if (gettimeofday(&v, 0) == 0) - return (UInt64)(v.tv_sec) * 1000000 + v.tv_usec; + if (gettimeofday(&v, NULL) == 0) + return (UInt64)(v.tv_sec) * 1000000 + (UInt64)v.tv_usec; return (UInt64)time(NULL) * 1000000; #else return time(NULL); #endif #else - /* LARGE_INTEGER value; if (::QueryPerformanceCounter(&value)) - return value.QuadPart; - */ + return (UInt64)value.QuadPart; return GetTickCount(); #endif } @@ -401,15 +412,14 @@ static UInt64 GetFreq() return 1; #endif #else - /* LARGE_INTEGER value; if (::QueryPerformanceFrequency(&value)) - return value.QuadPart; - */ + return (UInt64)value.QuadPart; return 1000; #endif } + #ifdef USE_POSIX_TIME struct CUserTime @@ -419,58 +429,106 @@ struct CUserTime void Init() { - Prev = clock(); + // Prev = clock(); + Sum = 0; + Prev = 0; + Update(); Sum = 0; } - UInt64 GetUserTime() + void Update() { + tms t; + /* clock_t res = */ times(&t); + clock_t newVal = t.tms_utime + t.tms_stime; + Sum += (UInt64)(newVal - Prev); + Prev = newVal; + + /* clock_t v = clock(); - Sum += v - Prev; - Prev = v; + if (v != -1) + { + Sum += v - Prev; + Prev = v; + } + */ + } + UInt64 GetUserTime() + { + Update(); return Sum; } }; #else -static inline UInt64 GetTime64(const FILETIME &t) { return ((UInt64)t.dwHighDateTime << 32) | t.dwLowDateTime; } -UInt64 GetWinUserTime() -{ - FILETIME creationTime, exitTime, kernelTime, userTime; - if ( - #ifdef UNDER_CE - ::GetThreadTimes(::GetCurrentThread() - #else - ::GetProcessTimes(::GetCurrentProcess() - #endif - , &creationTime, &exitTime, &kernelTime, &userTime) != 0) - return GetTime64(userTime) + GetTime64(kernelTime); - return (UInt64)GetTickCount() * 10000; -} struct CUserTime { - UInt64 StartTime; + bool UseTick; + DWORD Prev_Tick; + UInt64 Prev; + UInt64 Sum; - void Init() { StartTime = GetWinUserTime(); } - UInt64 GetUserTime() { return GetWinUserTime() - StartTime; } + void Init() + { + UseTick = false; + Prev_Tick = 0; + Prev = 0; + Sum = 0; + Update(); + Sum = 0; + } + UInt64 GetUserTime() + { + Update(); + return Sum; + } + void Update(); }; +static inline UInt64 GetTime64(const FILETIME &t) { return ((UInt64)t.dwHighDateTime << 32) | t.dwLowDateTime; } + +void CUserTime::Update() +{ + DWORD new_Tick = GetTickCount(); + FILETIME creationTime, exitTime, kernelTime, userTime; + if (!UseTick && + #ifdef UNDER_CE + ::GetThreadTimes(::GetCurrentThread() + #else + ::GetProcessTimes(::GetCurrentProcess() + #endif + , &creationTime, &exitTime, &kernelTime, &userTime)) + { + UInt64 newVal = GetTime64(userTime) + GetTime64(kernelTime); + Sum += newVal - Prev; + Prev = newVal; + } + else + { + UseTick = true; + Sum += (UInt64)(new_Tick - (DWORD)Prev_Tick) * 10000; + } + Prev_Tick = new_Tick; +} + + #endif static UInt64 GetUserFreq() { #ifdef USE_POSIX_TIME - return CLOCKS_PER_SEC; + // return CLOCKS_PER_SEC; + return (UInt64)sysconf(_SC_CLK_TCK); #else return 10000000; #endif } -class CBenchProgressStatus +class CBenchProgressStatus Z7_final { - #ifndef _7ZIP_ST + #ifndef Z7_ST NSynchronization::CCriticalSection CS; #endif public: @@ -478,14 +536,14 @@ public: bool EncodeMode; void SetResult(HRESULT res) { - #ifndef _7ZIP_ST + #ifndef Z7_ST NSynchronization::CCriticalSectionLock lock(CS); #endif Res = res; } HRESULT GetResult() { - #ifndef _7ZIP_ST + #ifndef Z7_ST NSynchronization::CCriticalSectionLock lock(CS); #endif return Res; @@ -517,28 +575,44 @@ void CBenchInfoCalc::SetFinishTime(CBenchInfo &dest) dest.UserTime = UserTime.GetUserTime(); } -class CBenchProgressInfo: +class CBenchProgressInfo Z7_final: public ICompressProgressInfo, public CMyUnknownImp, public CBenchInfoCalc { + Z7_COM_UNKNOWN_IMP_0 + Z7_IFACE_COM7_IMP(ICompressProgressInfo) public: CBenchProgressStatus *Status; - HRESULT Res; IBenchCallback *Callback; - CBenchProgressInfo(): Callback(0) {} - MY_UNKNOWN_IMP - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); + CBenchProgressInfo(): Callback(NULL) {} }; -STDMETHODIMP CBenchProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) + +Z7_COM7F_IMF(CBenchProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)) { HRESULT res = Status->GetResult(); if (res != S_OK) return res; if (!Callback) return res; + + /* + static UInt64 inSizePrev = 0; + static UInt64 outSizePrev = 0; + UInt64 delta1 = 0, delta2 = 0, val1 = 0, val2 = 0; + if (inSize) { val1 = *inSize; delta1 = val1 - inSizePrev; inSizePrev = val1; } + if (outSize) { val2 = *outSize; delta2 = val2 - outSizePrev; outSizePrev = val2; } + UInt64 percents = delta2 * 1000; + if (delta1 != 0) + percents /= delta1; + printf("=== %7d %7d %7d %7d ratio = %4d\n", + (unsigned)(val1 >> 10), (unsigned)(delta1 >> 10), + (unsigned)(val2 >> 10), (unsigned)(delta2 >> 10), + (unsigned)percents); + */ + CBenchInfo info; SetFinishTime(info); if (Status->EncodeMode) @@ -560,91 +634,168 @@ STDMETHODIMP CBenchProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 static const unsigned kSubBits = 8; -static UInt32 GetLogSize(UInt32 size) +static unsigned GetLogSize(UInt64 size) +{ + unsigned i = 0; + for (;;) + { + i++; size >>= 1; if (size == 0) break; + } + return i; +} + + +static UInt32 GetLogSize_Sub(UInt64 size) +{ + if (size <= 1) + return 0; + const unsigned i = GetLogSize(size) - 1; + UInt32 v; + if (i <= kSubBits) + v = (UInt32)(size) << (kSubBits - i); + else + v = (UInt32)(size >> (i - kSubBits)); + return ((UInt32)i << kSubBits) + (v & (((UInt32)1 << kSubBits) - 1)); +} + + +static UInt64 Get_UInt64_from_double(double v) { - for (unsigned i = kSubBits; i < 32; i++) - for (UInt32 j = 0; j < (1 << kSubBits); j++) - if (size <= (((UInt32)1) << i) + (j << (i - kSubBits))) - return (i << kSubBits) + j; - return (32 << kSubBits); + const UInt64 kMaxVal = (UInt64)1 << 62; + if (v > (double)(Int64)kMaxVal) + return kMaxVal; + return (UInt64)v; } -static void NormalizeVals(UInt64 &v1, UInt64 &v2) +static UInt64 MyMultDiv64(UInt64 m1, UInt64 m2, UInt64 d) { - while (v1 > 1000000) + if (d == 0) + d = 1; + const double v = + (double)(Int64)m1 * + (double)(Int64)m2 / + (double)(Int64)d; + return Get_UInt64_from_double(v); + /* + unsigned n1 = GetLogSize(m1); + unsigned n2 = GetLogSize(m2); + while (n1 + n2 > 64) { - v1 >>= 1; - v2 >>= 1; + if (n1 >= n2) + { + m1 >>= 1; + n1--; + } + else + { + m2 >>= 1; + n2--; + } + d >>= 1; } + + if (d == 0) + d = 1; + return m1 * m2 / d; + */ } + UInt64 CBenchInfo::GetUsage() const { UInt64 userTime = UserTime; UInt64 userFreq = UserFreq; UInt64 globalTime = GlobalTime; UInt64 globalFreq = GlobalFreq; - NormalizeVals(userTime, userFreq); - NormalizeVals(globalFreq, globalTime); + if (userFreq == 0) userFreq = 1; if (globalTime == 0) globalTime = 1; - return userTime * globalFreq * 1000000 / userFreq / globalTime; + + const double v = + ((double)(Int64)userTime / (double)(Int64)userFreq) + * ((double)(Int64)globalFreq / (double)(Int64)globalTime) + * (double)(Int64)kBenchmarkUsageMult; + return Get_UInt64_from_double(v); + /* + return MyMultDiv64( + MyMultDiv64(kBenchmarkUsageMult, userTime, userFreq), + globalFreq, globalTime); + */ } + UInt64 CBenchInfo::GetRatingPerUsage(UInt64 rating) const { - UInt64 userTime = UserTime; - UInt64 userFreq = UserFreq; - UInt64 globalTime = GlobalTime; + if (UserTime == 0) + { + return 0; + // userTime = 1; + } UInt64 globalFreq = GlobalFreq; - NormalizeVals(userFreq, userTime); - NormalizeVals(globalTime, globalFreq); if (globalFreq == 0) globalFreq = 1; - if (userTime == 0) - userTime = 1; - return userFreq * globalTime / globalFreq * rating / userTime; + + const double v = + ((double)(Int64)GlobalTime / (double)(Int64)globalFreq) + * ((double)(Int64)UserFreq / (double)(Int64)UserTime) + * (double)(Int64)rating; + return Get_UInt64_from_double(v); + /* + return MyMultDiv64( + MyMultDiv64(rating, UserFreq, UserTime), + GlobalTime, globalFreq); + */ } -static UInt64 MyMultDiv64(UInt64 value, UInt64 elapsedTime, UInt64 freq) + +UInt64 CBenchInfo::GetSpeed(UInt64 numUnits) const { - UInt64 elTime = elapsedTime; - NormalizeVals(freq, elTime); - if (elTime == 0) - elTime = 1; - return value * freq / elTime; + return MyMultDiv64(numUnits, GlobalFreq, GlobalTime); } -UInt64 CBenchInfo::GetSpeed(UInt64 numCommands) const +static UInt64 GetNumCommands_from_Size_and_Complexity(UInt64 size, Int32 complexity) { - return MyMultDiv64(numCommands, GlobalTime, GlobalFreq); + return complexity >= 0 ? + size * (UInt32)complexity : + size / (UInt32)(-complexity); } struct CBenchProps { bool LzmaRatingMode; - UInt32 EncComplex; - UInt32 DecComplexCompr; - UInt32 DecComplexUnc; + Int32 EncComplex; + Int32 DecComplexCompr; + Int32 DecComplexUnc; + + unsigned KeySize; + + CBenchProps(): + LzmaRatingMode(false), + KeySize(0) + {} - CBenchProps(): LzmaRatingMode(false) {} void SetLzmaCompexity(); - UInt64 GeComprCommands(UInt64 unpackSize) + UInt64 GetNumCommands_Enc(UInt64 unpackSize) const { - return unpackSize * EncComplex; + const UInt32 kMinSize = 100; + if (unpackSize < kMinSize) + unpackSize = kMinSize; + return GetNumCommands_from_Size_and_Complexity(unpackSize, EncComplex); } - UInt64 GeDecomprCommands(UInt64 packSize, UInt64 unpackSize) + UInt64 GetNumCommands_Dec(UInt64 packSize, UInt64 unpackSize) const { - return (packSize * DecComplexCompr + unpackSize * DecComplexUnc); + return + GetNumCommands_from_Size_and_Complexity(packSize, DecComplexCompr) + + GetNumCommands_from_Size_and_Complexity(unpackSize, DecComplexUnc); } - UInt64 GetCompressRating(UInt32 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size); - UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations); + UInt64 GetRating_Enc(UInt64 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size) const; + UInt64 GetRating_Dec(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations) const; }; void CBenchProps::SetLzmaCompexity() @@ -655,63 +806,247 @@ void CBenchProps::SetLzmaCompexity() LzmaRatingMode = true; } -UInt64 CBenchProps::GetCompressRating(UInt32 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size) +UInt64 CBenchProps::GetRating_Enc(UInt64 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size) const { if (dictSize < (1 << kBenchMinDicLogSize)) dictSize = (1 << kBenchMinDicLogSize); - UInt64 encComplex = EncComplex; + Int32 encComplex = EncComplex; if (LzmaRatingMode) { - UInt64 t = GetLogSize(dictSize) - (kBenchMinDicLogSize << kSubBits); + /* + for (UInt64 uu = 0; uu < (UInt64)0xf << 60;) + { + unsigned rr = GetLogSize_Sub(uu); + printf("\n%16I64x , log = %4x", uu, rr); + uu += 1; + uu += uu / 50; + } + */ + // throw 1; + const UInt32 t = GetLogSize_Sub(dictSize) - (kBenchMinDicLogSize << kSubBits); encComplex = 870 + ((t * t * 5) >> (2 * kSubBits)); } - UInt64 numCommands = (UInt64)size * encComplex; - return MyMultDiv64(numCommands, elapsedTime, freq); + const UInt64 numCommands = GetNumCommands_from_Size_and_Complexity(size, encComplex); + return MyMultDiv64(numCommands, freq, elapsedTime); } -UInt64 CBenchProps::GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations) +UInt64 CBenchProps::GetRating_Dec(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations) const { - UInt64 numCommands = (inSize * DecComplexCompr + outSize * DecComplexUnc) * numIterations; - return MyMultDiv64(numCommands, elapsedTime, freq); + const UInt64 numCommands = GetNumCommands_Dec(inSize, outSize) * numIterations; + return MyMultDiv64(numCommands, freq, elapsedTime); } -UInt64 GetCompressRating(UInt32 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size) + + +UInt64 CBenchInfo::GetRating_LzmaEnc(UInt64 dictSize) const { CBenchProps props; props.SetLzmaCompexity(); - return props.GetCompressRating(dictSize, elapsedTime, freq, size); + return props.GetRating_Enc(dictSize, GlobalTime, GlobalFreq, UnpackSize * NumIterations); } -UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations) +UInt64 CBenchInfo::GetRating_LzmaDec() const { CBenchProps props; props.SetLzmaCompexity(); - return props.GetDecompressRating(elapsedTime, freq, outSize, inSize, numIterations); + return props.GetRating_Dec(GlobalTime, GlobalFreq, UnpackSize, PackSize, NumIterations); +} + + +#ifndef Z7_ST + +#define NUM_CPU_LEVELS_MAX 3 + +struct CAffinityMode +{ + unsigned NumBundleThreads; + unsigned NumLevels; + unsigned NumCoreThreads; + unsigned NumCores; + // unsigned DivideNum; + UInt32 Sizes[NUM_CPU_LEVELS_MAX]; + + void SetLevels(unsigned numCores, unsigned numCoreThreads); + DWORD_PTR GetAffinityMask(UInt32 bundleIndex, CCpuSet *cpuSet) const; + bool NeedAffinity() const { return NumBundleThreads != 0; } + + WRes CreateThread_WithAffinity(NWindows::CThread &thread, THREAD_FUNC_TYPE startAddress, LPVOID parameter, UInt32 bundleIndex) const + { + if (NeedAffinity()) + { + CCpuSet cpuSet; + GetAffinityMask(bundleIndex, &cpuSet); + return thread.Create_With_CpuSet(startAddress, parameter, &cpuSet); + } + return thread.Create(startAddress, parameter); + } + + CAffinityMode(): + NumBundleThreads(0), + NumLevels(0), + NumCoreThreads(1) + // DivideNum(1) + {} +}; + +void CAffinityMode::SetLevels(unsigned numCores, unsigned numCoreThreads) +{ + NumCores = numCores; + NumCoreThreads = numCoreThreads; + NumLevels = 0; + if (numCoreThreads == 0 || numCores == 0 || numCores % numCoreThreads != 0) + return; + UInt32 c = numCores / numCoreThreads; + UInt32 c2 = 1; + while ((c & 1) == 0) + { + c >>= 1; + c2 <<= 1; + } + if (c2 != 1) + Sizes[NumLevels++] = c2; + if (c != 1) + Sizes[NumLevels++] = c; + if (numCoreThreads != 1) + Sizes[NumLevels++] = numCoreThreads; + if (NumLevels == 0) + Sizes[NumLevels++] = 1; + + /* + printf("\n Cores:"); + for (unsigned i = 0; i < NumLevels; i++) + { + printf(" %d", Sizes[i]); + } + printf("\n"); + */ +} + + +DWORD_PTR CAffinityMode::GetAffinityMask(UInt32 bundleIndex, CCpuSet *cpuSet) const +{ + CpuSet_Zero(cpuSet); + + if (NumLevels == 0) + return 0; + + // printf("\n%2d", bundleIndex); + + /* + UInt32 low = 0; + if (DivideNum != 1) + { + low = bundleIndex % DivideNum; + bundleIndex /= DivideNum; + } + */ + + UInt32 numGroups = NumCores / NumBundleThreads; + UInt32 m = bundleIndex % numGroups; + UInt32 v = 0; + for (unsigned i = 0; i < NumLevels; i++) + { + UInt32 size = Sizes[i]; + while ((size & 1) == 0) + { + v *= 2; + v |= (m & 1); + m >>= 1; + size >>= 1; + } + v *= size; + v += m % size; + m /= size; + } + + // UInt32 nb = NumBundleThreads / DivideNum; + UInt32 nb = NumBundleThreads; + + DWORD_PTR mask = ((DWORD_PTR)1 << nb) - 1; + // v += low; + mask <<= v; + + // printf(" %2d %8x \n ", v, (unsigned)mask); + #ifdef _WIN32 + *cpuSet = mask; + #else + { + for (unsigned k = 0; k < nb; k++) + CpuSet_Set(cpuSet, v + k); + } + #endif + + return mask; } -struct CEncoderInfo; -struct CEncoderInfo +struct CBenchSyncCommon +{ + bool ExitMode; + NSynchronization::CManualResetEvent StartEvent; + + CBenchSyncCommon(): ExitMode(false) {} +}; + +#endif + + + +enum E_CheckCrcMode { - #ifndef _7ZIP_ST + k_CheckCrcMode_Never = 0, + k_CheckCrcMode_Always = 1, + k_CheckCrcMode_FirstPass = 2 +}; + +class CEncoderInfo; + +class CEncoderInfo Z7_final +{ + Z7_CLASS_NO_COPY(CEncoderInfo) + +public: + + #ifndef Z7_ST NWindows::CThread thread[2]; + NSynchronization::CManualResetEvent ReadyEvent; UInt32 NumDecoderSubThreads; + CBenchSyncCommon *Common; + UInt32 EncoderIndex; + UInt32 NumEncoderInternalThreads; + CAffinityMode AffinityMode; + bool IsGlobalMtMode; // if more than one benchmark encoder threads #endif + CMyComPtr<ICompressCoder> _encoder; CMyComPtr<ICompressFilter> _encoderFilter; CBenchProgressInfo *progressInfoSpec[2]; CMyComPtr<ICompressProgressInfo> progressInfo[2]; UInt64 NumIterations; + UInt32 Salt; + #ifdef USE_ALLOCA size_t AllocaSize; #endif + unsigned KeySize; Byte _key[32]; Byte _iv[16]; + + HRESULT Set_Key_and_IV(ICryptoProperties *cp) + { + RINOK(cp->SetKey(_key, KeySize)) + return cp->SetInitVector(_iv, sizeof(_iv)); + } + Byte _psw[16]; - bool CheckCrc_Enc; - bool CheckCrc_Dec; + + bool CheckCrc_Enc; /* = 1, if we want to check packed data crcs after each pass + used for filter and usual coders */ + bool UseRealData_Enc; /* = 1, if we want to use only original data for each pass + used only for filter */ + E_CheckCrcMode CheckCrcMode_Dec; struct CDecoderInfo { @@ -741,28 +1076,41 @@ struct CEncoderInfo const Byte *fileData; CBenchRandomGenerator rg; - CBenchBuffer rgCopy; // it must be 16-byte aligned !!! - CBenchmarkOutStream *propStreamSpec; + CMidAlignedBuffer rgCopy; // it must be 16-byte aligned !!! + + // CBenchmarkOutStream *propStreamSpec; + Byte propsData[kMaxMethodPropSize]; + CBufPtrSeqOutStream *propStreamSpec; CMyComPtr<ISequentialOutStream> propStream; - // for decode + unsigned generateDictBits; COneMethodInfo _method; + + // for decode size_t _uncompressedDataSize; - HRESULT Init( - const COneMethodInfo &method, - unsigned generateDictBits, - CBaseRandomGenerator *rg); + HRESULT Generate(); HRESULT Encode(); HRESULT Decode(UInt32 decoderIndex); CEncoderInfo(): - fileData(NULL), + #ifndef Z7_ST + Common(NULL), + IsGlobalMtMode(true), + #endif + Salt(0), + KeySize(0), CheckCrc_Enc(true), - CheckCrc_Dec(true), - outStreamSpec(0), callback(0), printCallback(0), propStreamSpec(0) {} + UseRealData_Enc(true), + CheckCrcMode_Dec(k_CheckCrcMode_Always), + outStreamSpec(NULL), + callback(NULL), + printCallback(NULL), + fileData(NULL), + propStreamSpec(NULL) + {} - #ifndef _7ZIP_ST + #ifndef Z7_ST static THREAD_FUNC_DECL EncodeThreadFunction(void *param) { @@ -775,15 +1123,16 @@ struct CEncoderInfo #endif res = encoder->Encode(); - encoder->Results[0] = res; } catch(...) { res = E_FAIL; } + encoder->Results[0] = res; if (res != S_OK) encoder->progressInfoSpec[0]->Status->SetResult(res); - return 0; + encoder->ReadyEvent.Set(); + return THREAD_FUNC_RET_ZERO; } static THREAD_FUNC_DECL DecodeThreadFunction(void *param) @@ -796,12 +1145,18 @@ struct CEncoderInfo CEncoderInfo *encoder = decoder->Encoder; encoder->Results[decoder->DecoderIndex] = encoder->Decode(decoder->DecoderIndex); - return 0; + return THREAD_FUNC_RET_ZERO; } HRESULT CreateEncoderThread() { - return thread[0].Create(EncodeThreadFunction, this); + WRes res = 0; + if (!ReadyEvent.IsCreated()) + res = ReadyEvent.Create(); + if (res == 0) + res = AffinityMode.CreateThread_WithAffinity(thread[0], EncodeThreadFunction, this, + EncoderIndex); + return HRESULT_FROM_WIN32(res); } HRESULT CreateDecoderThread(unsigned index, bool callbackMode @@ -819,66 +1174,99 @@ struct CEncoderInfo #endif decoder.CallbackMode = callbackMode; - return thread[index].Create(DecodeThreadFunction, &decoder); + + WRes res = AffinityMode.CreateThread_WithAffinity(thread[index], DecodeThreadFunction, &decoder, + // EncoderIndex * NumEncoderInternalThreads + index + EncoderIndex + ); + + return HRESULT_FROM_WIN32(res); } #endif }; -HRESULT CEncoderInfo::Init( - const COneMethodInfo &method, - unsigned generateDictBits, - CBaseRandomGenerator *rgLoc) + + +static size_t GetBenchCompressedSize(size_t bufferSize) +{ + return kCompressedAdditionalSize + bufferSize + bufferSize / 16; + // kBufferSize / 2; +} + + +HRESULT CEncoderInfo::Generate() { + const COneMethodInfo &method = _method; + // we need extra space, if input data is already compressed - const size_t kCompressedBufferSize = - kCompressedAdditionalSize + - kBufferSize + kBufferSize / 16; - // kBufferSize / 2; + const size_t kCompressedBufferSize = _encoderFilter ? + kBufferSize : + GetBenchCompressedSize(kBufferSize); if (kCompressedBufferSize < kBufferSize) return E_FAIL; uncompressedDataPtr = fileData; - - if (!fileData) + if (fileData) { - if (!rg.Alloc(kBufferSize)) - return E_OUTOFMEMORY; - + #if !defined(Z7_ST) + if (IsGlobalMtMode) + { + /* we copy the data to local buffer of thread to eliminate + using of shared buffer by different threads */ + ALLOC_WITH_HRESULT(&rg, kBufferSize) + memcpy((Byte *)rg, fileData, kBufferSize); + uncompressedDataPtr = (const Byte *)rg; + } + #endif + } + else + { + ALLOC_WITH_HRESULT(&rg, kBufferSize) // DWORD ttt = GetTickCount(); if (generateDictBits == 0) - rg.GenerateSimpleRandom(rgLoc); + rg.GenerateSimpleRandom(Salt); else - rg.GenerateLz(generateDictBits, rgLoc); + { + if (generateDictBits >= sizeof(size_t) * 8 + && kBufferSize > ((size_t)1 << (sizeof(size_t) * 8 - 1))) + return E_INVALIDARG; + rg.GenerateLz(generateDictBits, Salt); + // return E_ABORT; // for debug + } // printf("\n%d\n ", GetTickCount() - ttt); - crc = CrcCalc(rg.Buffer, rg.BufferSize); - uncompressedDataPtr = rg.Buffer; + crc = CrcCalc((const Byte *)rg, rg.Size()); + uncompressedDataPtr = (const Byte *)rg; } - - if (_encoderFilter) + + if (!outStream) { - if (!rgCopy.Alloc(kBufferSize)) - return E_OUTOFMEMORY; + outStreamSpec = new CBenchmarkOutStream; + outStream = outStreamSpec; } + ALLOC_WITH_HRESULT(outStreamSpec, kCompressedBufferSize) - outStreamSpec = new CBenchmarkOutStream; - outStream = outStreamSpec; - if (!outStreamSpec->Alloc(kCompressedBufferSize)) - return E_OUTOFMEMORY; + if (_encoderFilter) + { + /* we try to reduce the number of memcpy() in main encoding loop. + so we copy data to temp buffers here */ + ALLOC_WITH_HRESULT(&rgCopy, kBufferSize) + memcpy((Byte *)*outStreamSpec, uncompressedDataPtr, kBufferSize); + memcpy((Byte *)rgCopy, uncompressedDataPtr, kBufferSize); + } - propStreamSpec = 0; if (!propStream) { - propStreamSpec = new CBenchmarkOutStream; + propStreamSpec = new CBufPtrSeqOutStream; // CBenchmarkOutStream; propStream = propStreamSpec; } - if (!propStreamSpec->Alloc(kMaxLzmaPropSize)) - return E_OUTOFMEMORY; - propStreamSpec->Init(true, false); + // ALLOC_WITH_HRESULT_2(propStreamSpec, kMaxMethodPropSize); + // propStreamSpec->Init(true, false); + propStreamSpec->Init(propsData, sizeof(propsData)); CMyComPtr<IUnknown> coder; @@ -891,8 +1279,23 @@ HRESULT CEncoderInfo::Init( coder.QueryInterface(IID_ICompressSetCoderProperties, &scp); if (scp) { - UInt64 reduceSize = kBufferSize; - RINOK(method.SetCoderProps(scp, &reduceSize)); + const UInt64 reduceSize = kBufferSize; + + /* in posix new thread uses same affinity as parent thread, + so we don't need to send affinity to coder in posix */ + UInt64 affMask; + #if !defined(Z7_ST) && defined(_WIN32) + { + CCpuSet cpuSet; + affMask = AffinityMode.GetAffinityMask(EncoderIndex, &cpuSet); + } + #else + affMask = 0; + #endif + // affMask <<= 3; // debug line: to test no affinity in coder; + // affMask = 0; + + RINOK(method.SetCoderProps_DSReduce_Aff(scp, &reduceSize, (affMask != 0 ? &affMask : NULL))) } else { @@ -904,7 +1307,7 @@ HRESULT CEncoderInfo::Init( coder.QueryInterface(IID_ICompressWriteCoderProperties, &writeCoderProps); if (writeCoderProps) { - RINOK(writeCoderProps->WriteCoderProperties(propStream)); + RINOK(writeCoderProps->WriteCoderProperties(propStream)) } { @@ -912,7 +1315,7 @@ HRESULT CEncoderInfo::Init( coder.QueryInterface(IID_ICryptoSetPassword, &sp); if (sp) { - RINOK(sp->CryptoSetPassword(_psw, sizeof(_psw))); + RINOK(sp->CryptoSetPassword(_psw, sizeof(_psw))) // we must call encoding one time to calculate password key for key cache. // it must be after WriteCoderProperties! @@ -934,7 +1337,7 @@ HRESULT CEncoderInfo::Init( CMyComPtr<ISequentialOutStream> crcStream = crcStreamSpec; crcStreamSpec->Init(); - RINOK(_encoder->Code(inStream, crcStream, 0, 0, NULL)); + RINOK(_encoder->Code(inStream, crcStream, NULL, NULL, NULL)) } } } @@ -944,19 +1347,22 @@ HRESULT CEncoderInfo::Init( } -static void My_FilterBench(ICompressFilter *filter, Byte *data, size_t size) +static void My_FilterBench(ICompressFilter *filter, Byte *data, size_t size, UInt32 *crc) { while (size != 0) { - UInt32 cur = (UInt32)1 << 31; + UInt32 cur = crc ? 1 << 17 : 1 << 24; if (cur > size) cur = (UInt32)size; UInt32 processed = filter->Filter(data, cur); - data += processed; - // if (processed > size) (in AES filter), we must fill last block with zeros. - // but it is not important for benchmark. So we just copy that data without filtering. + /* if (processed > size) (in AES filter), we must fill last block with zeros. + but it is not important for benchmark. So we just copy that data without filtering. + if (processed == 0) then filter can't process more */ if (processed > size || processed == 0) - break; + processed = (UInt32)size; + if (crc) + *crc = CrcUpdate(*crc, data, processed); + data += processed; size -= processed; } } @@ -964,6 +1370,32 @@ static void My_FilterBench(ICompressFilter *filter, Byte *data, size_t size) HRESULT CEncoderInfo::Encode() { + // printf("\nCEncoderInfo::Generate\n"); + + RINOK(Generate()) + + // printf("\n2222\n"); + + #ifndef Z7_ST + if (Common) + { + Results[0] = S_OK; + WRes wres = ReadyEvent.Set(); + if (wres == 0) + wres = Common->StartEvent.Lock(); + if (wres != 0) + return HRESULT_FROM_WIN32(wres); + if (Common->ExitMode) + return S_OK; + } + else + #endif + { + CBenchProgressInfo *bpi = progressInfoSpec[0]; + bpi->SetStartTime(); + } + + CBenchInfo &bi = progressInfoSpec[0]->BenchInfo; bi.UnpackSize = 0; bi.PackSize = 0; @@ -976,52 +1408,116 @@ HRESULT CEncoderInfo::Encode() coder.QueryInterface(IID_ICryptoProperties, &cp); CBenchmarkInStream *inStreamSpec = new CBenchmarkInStream; CMyComPtr<ISequentialInStream> inStream = inStreamSpec; - UInt64 prev = 0; - - UInt32 crcPrev = 0; if (cp) { - RINOK(cp->SetKey(_key, sizeof(_key))); - RINOK(cp->SetInitVector(_iv, sizeof(_iv))); + RINOK(Set_Key_and_IV(cp)) + } + + compressedSize = 0; + if (_encoderFilter) + compressedSize = kBufferSize; + + // CBenchmarkOutStream *outStreamSpec = this->outStreamSpec; + UInt64 prev = 0; + + const UInt32 mask = (CheckCrc_Enc ? 0 : 0xFFFF); + const bool useCrc = (mask < NumIterations); + bool crcPrev_defined = false; + UInt32 crcPrev = 0; + + bool useRealData_Enc = UseRealData_Enc; + bool data_Was_Changed = false; + if (useRealData_Enc) + { + /* we want memcpy() for each iteration including first iteration. + So results will be equal for different number of iterations */ + data_Was_Changed = true; } - for (UInt64 i = 0; i < NumIterations; i++) + const UInt64 numIterations = NumIterations; + UInt64 i = numIterations; + // printCallback->NewLine(); + + while (i != 0) { - if (printCallback && bi.UnpackSize - prev > (1 << 20)) + i--; + if (printCallback && bi.UnpackSize - prev >= (1 << 26)) { - RINOK(printCallback->CheckBreak()); prev = bi.UnpackSize; + RINOK(printCallback->CheckBreak()) } + + /* + CBenchInfo info; + progressInfoSpec[0]->SetStartTime(); + */ - bool isLast = (i == NumIterations - 1); - bool calcCrc = ((isLast || (i & 0x7F) == 0 || CheckCrc_Enc) && NumIterations != 1); - outStreamSpec->Init(isLast, calcCrc); - + bool calcCrc = false; + if (useCrc) + calcCrc = (((UInt32)i & mask) == 0); + if (_encoderFilter) { - memcpy(rgCopy.Buffer, uncompressedDataPtr, kBufferSize); + Byte *filterData = rgCopy; + if (i == numIterations - 1 || calcCrc || useRealData_Enc) + { + filterData = (Byte *)*outStreamSpec; + if (data_Was_Changed) + memcpy(filterData, uncompressedDataPtr, kBufferSize); + data_Was_Changed = true; + } _encoderFilter->Init(); - My_FilterBench(_encoderFilter, rgCopy.Buffer, kBufferSize); - RINOK(WriteStream(outStream, rgCopy.Buffer, kBufferSize)); + if (calcCrc) + outStreamSpec->InitCrc(); + My_FilterBench(_encoderFilter, filterData, kBufferSize, + calcCrc ? &outStreamSpec->Crc : NULL); } else { + outStreamSpec->Init(true, calcCrc); // write real data for speed consistency at any number of iterations inStreamSpec->Init(uncompressedDataPtr, kBufferSize); - RINOK(_encoder->Code(inStream, outStream, NULL, NULL, progressInfo[0])); + RINOK(_encoder->Code(inStream, outStream, NULL, NULL, progressInfo[0])) + if (!inStreamSpec->WasFinished()) + return E_FAIL; + if (compressedSize != outStreamSpec->Pos) + { + if (compressedSize != 0) + return E_FAIL; + compressedSize = outStreamSpec->Pos; + } } // outStreamSpec->Print(); - UInt32 crcNew = CRC_GET_DIGEST(outStreamSpec->Crc); - if (i == 0) - crcPrev = crcNew; - else if (calcCrc && crcPrev != crcNew) - return E_FAIL; + if (calcCrc) + { + const UInt32 crc2 = CRC_GET_DIGEST(outStreamSpec->Crc); + if (crcPrev_defined && crcPrev != crc2) + return E_FAIL; + crcPrev = crc2; + crcPrev_defined = true; + } - compressedSize = outStreamSpec->Pos; bi.UnpackSize += kBufferSize; bi.PackSize += compressedSize; + + /* + { + progressInfoSpec[0]->SetFinishTime(info); + info.UnpackSize = 0; + info.PackSize = 0; + info.NumIterations = 1; + + info.UnpackSize = kBufferSize; + info.PackSize = compressedSize; + // printf("\n%7d\n", encoder.compressedSize); + + RINOK(callback->SetEncodeResult(info, true)) + printCallback->NewLine(); + } + */ + } _encoder.Release(); @@ -1047,7 +1543,7 @@ HRESULT CEncoderInfo::Decode(UInt32 decoderIndex) CMyComPtr<ICompressSetDecoderProperties2> setDecProps; coder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecProps); - if (!setDecProps && propStreamSpec->Pos != 0) + if (!setDecProps && propStreamSpec->GetPos() != 0) return E_FAIL; CCrcOutStream *crcOutStreamSpec = new CCrcOutStream; @@ -1057,13 +1553,13 @@ HRESULT CEncoderInfo::Decode(UInt32 decoderIndex) pi->BenchInfo.UnpackSize = 0; pi->BenchInfo.PackSize = 0; - #ifndef _7ZIP_ST + #ifndef Z7_ST { CMyComPtr<ICompressSetCoderMt> setCoderMt; coder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt); if (setCoderMt) { - RINOK(setCoderMt->SetNumberOfThreads(NumDecoderSubThreads)); + RINOK(setCoderMt->SetNumberOfThreads(NumDecoderSubThreads)) } } #endif @@ -1072,8 +1568,8 @@ HRESULT CEncoderInfo::Decode(UInt32 decoderIndex) coder.QueryInterface(IID_ICompressSetCoderProperties, &scp); if (scp) { - UInt64 reduceSize = _uncompressedDataSize; - RINOK(_method.SetCoderProps(scp, &reduceSize)); + const UInt64 reduceSize = _uncompressedDataSize; + RINOK(_method.SetCoderProps(scp, &reduceSize)) } CMyComPtr<ICryptoProperties> cp; @@ -1081,7 +1577,10 @@ HRESULT CEncoderInfo::Decode(UInt32 decoderIndex) if (setDecProps) { - RINOK(setDecProps->SetDecoderProperties2(propStreamSpec->Buffer, (UInt32)propStreamSpec->Pos)); + RINOK(setDecProps->SetDecoderProperties2( + /* (const Byte *)*propStreamSpec, */ + propsData, + (UInt32)propStreamSpec->GetPos())) } { @@ -1089,7 +1588,7 @@ HRESULT CEncoderInfo::Decode(UInt32 decoderIndex) coder.QueryInterface(IID_ICryptoSetPassword, &sp); if (sp) { - RINOK(sp->CryptoSetPassword(_psw, sizeof(_psw))); + RINOK(sp->CryptoSetPassword(_psw, sizeof(_psw))) } } @@ -1097,40 +1596,90 @@ HRESULT CEncoderInfo::Decode(UInt32 decoderIndex) if (cp) { - RINOK(cp->SetKey(_key, sizeof(_key))); - RINOK(cp->SetInitVector(_iv, sizeof(_iv))); + RINOK(Set_Key_and_IV(cp)) } - for (UInt64 i = 0; i < NumIterations; i++) + CMyComPtr<ICompressSetFinishMode> setFinishMode; + + if (_decoderFilter) { - if (printCallback && pi->BenchInfo.UnpackSize - prev > (1 << 20)) + if (compressedSize > rgCopy.Size()) + return E_FAIL; + } + else + { + decoder->QueryInterface(IID_ICompressSetFinishMode, (void **)&setFinishMode); + } + + const UInt64 numIterations = NumIterations; + const E_CheckCrcMode checkCrcMode = CheckCrcMode_Dec; + + for (UInt64 i = 0; i < numIterations; i++) + { + if (printCallback && pi->BenchInfo.UnpackSize - prev >= (1 << 26)) { - RINOK(printCallback->CheckBreak()); + RINOK(printCallback->CheckBreak()) prev = pi->BenchInfo.UnpackSize; } - inStreamSpec->Init(outStreamSpec->Buffer, compressedSize); + const UInt64 outSize = kBufferSize; + bool calcCrc = (checkCrcMode != k_CheckCrcMode_Never); + crcOutStreamSpec->Init(); - - UInt64 outSize = kBufferSize; - crcOutStreamSpec->CalcCrc = ((i & 0x7F) == 0 || CheckCrc_Dec); - + if (_decoderFilter) { - if (compressedSize > rgCopy.BufferSize) - return E_FAIL; - memcpy(rgCopy.Buffer, outStreamSpec->Buffer, compressedSize); + Byte *filterData = (Byte *)*outStreamSpec; + if (calcCrc) + { + calcCrc = (i == 0); + if (checkCrcMode == k_CheckCrcMode_Always) + { + calcCrc = true; + memcpy((Byte *)rgCopy, (const Byte *)*outStreamSpec, compressedSize); + filterData = rgCopy; + } + } _decoderFilter->Init(); - My_FilterBench(_decoderFilter, rgCopy.Buffer, compressedSize); - RINOK(WriteStream(crcOutStream, rgCopy.Buffer, compressedSize)); + My_FilterBench(_decoderFilter, filterData, compressedSize, + calcCrc ? &crcOutStreamSpec->Crc : NULL); } else { - RINOK(decoder->Code(inStream, crcOutStream, 0, &outSize, progressInfo[decoderIndex])); + crcOutStreamSpec->CalcCrc = calcCrc; + inStreamSpec->Init((const Byte *)*outStreamSpec, compressedSize); + + if (setFinishMode) + { + RINOK(setFinishMode->SetFinishMode(BoolToUInt(true))) + } + + RINOK(decoder->Code(inStream, crcOutStream, NULL, &outSize, progressInfo[decoderIndex])) + + if (setFinishMode) + { + if (!inStreamSpec->WasFinished()) + return S_FALSE; + + CMyComPtr<ICompressGetInStreamProcessedSize> getInStreamProcessedSize; + decoder.QueryInterface(IID_ICompressGetInStreamProcessedSize, (void **)&getInStreamProcessedSize); + + if (getInStreamProcessedSize) + { + UInt64 processed; + RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(&processed)) + if (processed != compressedSize) + return S_FALSE; + } + } + + if (crcOutStreamSpec->Pos != outSize) + return S_FALSE; } - if (crcOutStreamSpec->CalcCrc && CRC_GET_DIGEST(crcOutStreamSpec->Crc) != crc) + if (calcCrc && CRC_GET_DIGEST(crcOutStreamSpec->Crc) != crc) return S_FALSE; + pi->BenchInfo.UnpackSize += kBufferSize; pi->BenchInfo.PackSize += compressedSize; } @@ -1146,7 +1695,7 @@ static const UInt32 kNumThreadsMax = (1 << 12); struct CBenchEncoders { CEncoderInfo *encoders; - CBenchEncoders(UInt32 num): encoders(0) { encoders = new CEncoderInfo[num]; } + CBenchEncoders(UInt32 num): encoders(NULL) { encoders = new CEncoderInfo[num]; } ~CBenchEncoders() { delete []encoders; } }; @@ -1160,19 +1709,74 @@ static UInt64 GetNumIterations(UInt64 numCommands, UInt64 complexInCommands) } + +#ifndef Z7_ST + +// ---------- CBenchThreadsFlusher ---------- + +struct CBenchThreadsFlusher +{ + CBenchEncoders *EncodersSpec; + CBenchSyncCommon Common; + unsigned NumThreads; + bool NeedClose; + + CBenchThreadsFlusher(): NumThreads(0), NeedClose(false) {} + + ~CBenchThreadsFlusher() + { + StartAndWait(true); + } + + WRes StartAndWait(bool exitMode = false); +}; + + +WRes CBenchThreadsFlusher::StartAndWait(bool exitMode) +{ + if (!NeedClose) + return 0; + + Common.ExitMode = exitMode; + WRes res = Common.StartEvent.Set(); + + for (unsigned i = 0; i < NumThreads; i++) + { + NWindows::CThread &t = EncodersSpec->encoders[i].thread[0]; + if (t.IsCreated()) + { + WRes res2 = t.Wait_Close(); + if (res == 0) + res = res2; + } + } + NeedClose = false; + return res; +} + +#endif // Z7_ST + + + +static void SetPseudoRand(Byte *data, size_t size, UInt32 startValue) +{ + for (size_t i = 0; i < size; i++) + { + data[i] = (Byte)startValue; + startValue++; + } +} + + + static HRESULT MethodBench( DECL_EXTERNAL_CODECS_LOC_VARS UInt64 complexInCommands, - bool - #ifndef _7ZIP_ST - oldLzmaBenchMode - #endif - , - UInt32 - #ifndef _7ZIP_ST - numThreads - #endif - , + #ifndef Z7_ST + bool oldLzmaBenchMode, + UInt32 numThreads, + const CAffinityMode *affinityMode, + #endif const COneMethodInfo &method2, size_t uncompressedDataSize, const Byte *fileData, @@ -1185,9 +1789,12 @@ static HRESULT MethodBench( COneMethodInfo method = method2; UInt64 methodId; UInt32 numStreams; - if (!FindMethod( + bool isFilter; + const int codecIndex = FindMethod_Index( EXTERNAL_CODECS_LOC_VARS - method.MethodName, methodId, numStreams)) + method.MethodName, true, + methodId, numStreams, isFilter); + if (codecIndex < 0) return E_NOTIMPL; if (numStreams != 1) return E_INVALIDARG; @@ -1195,21 +1802,24 @@ static HRESULT MethodBench( UInt32 numEncoderThreads = 1; UInt32 numSubDecoderThreads = 1; - #ifndef _7ZIP_ST + #ifndef Z7_ST numEncoderThreads = numThreads; - if (oldLzmaBenchMode && methodId == k_LZMA) + if (oldLzmaBenchMode) + if (methodId == k_LZMA) { - bool fixedNumber; - UInt32 numLzmaThreads = method.Get_Lzma_NumThreads(fixedNumber); - if (!fixedNumber && numThreads == 1) + if (numThreads == 1 && method.Get_NumThreads() < 0) method.AddProp_NumThreads(1); + const UInt32 numLzmaThreads = method.Get_Lzma_NumThreads(); if (numThreads > 1 && numLzmaThreads > 1) { - numEncoderThreads = numThreads / 2; + numEncoderThreads = (numThreads + 1) / 2; // 20.03 numSubDecoderThreads = 2; } } + + const bool mtEncMode = (numEncoderThreads > 1) || affinityMode->NeedAffinity(); + #endif CBenchEncoders encodersSpec(numEncoderThreads); @@ -1220,37 +1830,65 @@ static HRESULT MethodBench( for (i = 0; i < numEncoderThreads; i++) { CEncoderInfo &encoder = encoders[i]; - encoder.callback = (i == 0) ? callback : 0; + encoder.callback = (i == 0) ? callback : NULL; encoder.printCallback = printCallback; + #ifndef Z7_ST + encoder.EncoderIndex = i; + encoder.NumEncoderInternalThreads = numSubDecoderThreads; + encoder.AffinityMode = *affinityMode; + + /* + if (numSubDecoderThreads > 1) + if (encoder.AffinityMode.NeedAffinity() + && encoder.AffinityMode.NumBundleThreads == 1) + { + // if old LZMA benchmark uses two threads in coder, we increase (NumBundleThreads) for old LZMA benchmark uses two threads instead of one + if (encoder.AffinityMode.NumBundleThreads * 2 <= encoder.AffinityMode.NumCores) + encoder.AffinityMode.NumBundleThreads *= 2; + } + */ + + #endif + { CCreatedCoder cod; - RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS methodId, true, encoder._encoderFilter, cod)); + RINOK(CreateCoder_Index(EXTERNAL_CODECS_LOC_VARS (unsigned)codecIndex, true, encoder._encoderFilter, cod)) encoder._encoder = cod.Coder; if (!encoder._encoder && !encoder._encoderFilter) return E_NOTIMPL; } - encoder.CheckCrc_Enc = (benchProps->EncComplex) > 30 ; - encoder.CheckCrc_Dec = (benchProps->DecComplexCompr + benchProps->DecComplexUnc) > 30 ; - - memset(encoder._iv, 0, sizeof(encoder._iv)); - memset(encoder._key, 0, sizeof(encoder._key)); - memset(encoder._psw, 0, sizeof(encoder._psw)); + SetPseudoRand(encoder._iv, sizeof(encoder._iv), 17); + SetPseudoRand(encoder._key, sizeof(encoder._key), 51); + SetPseudoRand(encoder._psw, sizeof(encoder._psw), 123); for (UInt32 j = 0; j < numSubDecoderThreads; j++) { CCreatedCoder cod; CMyComPtr<ICompressCoder> &decoder = encoder._decoders[j]; - RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS methodId, false, encoder._decoderFilter, cod)); + RINOK(CreateCoder_Id(EXTERNAL_CODECS_LOC_VARS methodId, false, encoder._decoderFilter, cod)) decoder = cod.Coder; if (!encoder._decoderFilter && !decoder) return E_NOTIMPL; } - } - CBaseRandomGenerator rg; - rg.Init(); + encoder.UseRealData_Enc = + encoder.CheckCrc_Enc = (benchProps->EncComplex) > 30; + + encoder.CheckCrcMode_Dec = k_CheckCrcMode_Always; + if (benchProps->DecComplexCompr + + benchProps->DecComplexUnc <= 30) + encoder.CheckCrcMode_Dec = + k_CheckCrcMode_FirstPass; // for filters + // k_CheckCrcMode_Never; // for debug + // k_CheckCrcMode_Always; // for debug + if (fileData) + { + encoder.UseRealData_Enc = true; + encoder.CheckCrcMode_Dec = k_CheckCrcMode_Always; + } + } UInt32 crc = 0; if (fileData) @@ -1260,22 +1898,41 @@ static HRESULT MethodBench( { CEncoderInfo &encoder = encoders[i]; encoder._method = method; + encoder.generateDictBits = generateDictBits; encoder._uncompressedDataSize = uncompressedDataSize; encoder.kBufferSize = uncompressedDataSize; encoder.fileData = fileData; encoder.crc = crc; - - RINOK(encoders[i].Init(method, generateDictBits, &rg)); } CBenchProgressStatus status; status.Res = S_OK; status.EncodeMode = true; + #ifndef Z7_ST + CBenchThreadsFlusher encoderFlusher; + if (mtEncMode) + { + WRes wres = encoderFlusher.Common.StartEvent.Create(); + if (wres != 0) + return HRESULT_FROM_WIN32(wres); + encoderFlusher.NumThreads = numEncoderThreads; + encoderFlusher.EncodersSpec = &encodersSpec; + encoderFlusher.NeedClose = true; + } + #endif + for (i = 0; i < numEncoderThreads; i++) { CEncoderInfo &encoder = encoders[i]; - encoder.NumIterations = GetNumIterations(benchProps->GeComprCommands(uncompressedDataSize), complexInCommands); + encoder.NumIterations = GetNumIterations(benchProps->GetNumCommands_Enc(uncompressedDataSize), complexInCommands); + // encoder.NumIterations = 3; + encoder.Salt = g_CrcTable[i & 0xFF]; + encoder.Salt ^= (g_CrcTable[(i >> 8) & 0xFF] << 3); + // (g_CrcTable[0] == 0), and (encoder.Salt == 0) for first thread + // printf(" %8x", encoder.Salt); + + encoder.KeySize = benchProps->KeySize; for (int j = 0; j < 2; j++) { @@ -1290,32 +1947,53 @@ static HRESULT MethodBench( CBenchProgressInfo *bpi = encoder.progressInfoSpec[0]; bpi->Callback = callback; bpi->BenchInfo.NumIterations = numEncoderThreads; - bpi->SetStartTime(); } - #ifndef _7ZIP_ST - if (numEncoderThreads > 1) + #ifndef Z7_ST + if (mtEncMode) { #ifdef USE_ALLOCA encoder.AllocaSize = (i * 16 * 21) & 0x7FF; #endif + encoder.Common = &encoderFlusher.Common; + encoder.IsGlobalMtMode = numEncoderThreads > 1; RINOK(encoder.CreateEncoderThread()) } - else #endif + } + + if (printCallback) + { + RINOK(printCallback->CheckBreak()) + } + + #ifndef Z7_ST + if (mtEncMode) + { + for (i = 0; i < numEncoderThreads; i++) { - RINOK(encoder.Encode()); + CEncoderInfo &encoder = encoders[i]; + const WRes wres = encoder.ReadyEvent.Lock(); + if (wres != 0) + return HRESULT_FROM_WIN32(wres); + RINOK(encoder.Results[0]) } + + CBenchProgressInfo *bpi = encoders[0].progressInfoSpec[0]; + bpi->SetStartTime(); + + const WRes wres = encoderFlusher.StartAndWait(); + if (status.Res == 0 && wres != 0) + return HRESULT_FROM_WIN32(wres); } - - #ifndef _7ZIP_ST - if (numEncoderThreads > 1) - for (i = 0; i < numEncoderThreads; i++) - encoders[i].thread[0].Wait(); + else #endif + { + RINOK(encoders[0].Encode()) + } - RINOK(status.Res); + RINOK(status.Res) CBenchInfo info; @@ -1326,26 +2004,47 @@ static HRESULT MethodBench( for (i = 0; i < numEncoderThreads; i++) { - CEncoderInfo &encoder = encoders[i]; + const CEncoderInfo &encoder = encoders[i]; info.UnpackSize += encoder.kBufferSize; info.PackSize += encoder.compressedSize; + // printf("\n%7d\n", encoder.compressedSize); } - RINOK(callback->SetEncodeResult(info, true)); + RINOK(callback->SetEncodeResult(info, true)) + + + // ---------- Decode ---------- + status.Res = S_OK; status.EncodeMode = false; - UInt32 numDecoderThreads = numEncoderThreads * numSubDecoderThreads; + const UInt32 numDecoderThreads = numEncoderThreads * numSubDecoderThreads; + #ifndef Z7_ST + const bool mtDecoderMode = (numDecoderThreads > 1) || affinityMode->NeedAffinity(); + #endif for (i = 0; i < numEncoderThreads; i++) { CEncoderInfo &encoder = encoders[i]; + /* + #ifndef Z7_ST + // encoder.affinityMode = *affinityMode; + if (encoder.NumEncoderInternalThreads != 1) + encoder.AffinityMode.DivideNum = encoder.NumEncoderInternalThreads; + #endif + */ + + if (i == 0) { - encoder.NumIterations = GetNumIterations(benchProps->GeDecomprCommands(encoder.compressedSize, encoder.kBufferSize), complexInCommands); + encoder.NumIterations = GetNumIterations( + benchProps->GetNumCommands_Dec( + encoder.compressedSize, + encoder.kBufferSize), + complexInCommands); CBenchProgressInfo *bpi = encoder.progressInfoSpec[0]; bpi->Callback = callback; bpi->BenchInfo.NumIterations = numDecoderThreads; @@ -1354,50 +2053,61 @@ static HRESULT MethodBench( else encoder.NumIterations = encoders[0].NumIterations; - #ifndef _7ZIP_ST + #ifndef Z7_ST { int numSubThreads = method.Get_NumThreads(); - encoder.NumDecoderSubThreads = (numSubThreads <= 0) ? 1 : numSubThreads; + encoder.NumDecoderSubThreads = (numSubThreads <= 0) ? 1 : (unsigned)numSubThreads; } - if (numDecoderThreads > 1) + if (mtDecoderMode) { for (UInt32 j = 0; j < numSubDecoderThreads; j++) { - HRESULT res = encoder.CreateDecoderThread(j, (i == 0 && j == 0) + const HRESULT res = encoder.CreateDecoderThread(j, (i == 0 && j == 0) #ifdef USE_ALLOCA , ((i * numSubDecoderThreads + j) * 16 * 21) & 0x7FF #endif ); - RINOK(res); + RINOK(res) } } else #endif { - RINOK(encoder.Decode(0)); + RINOK(encoder.Decode(0)) } } - #ifndef _7ZIP_ST - HRESULT res = S_OK; - if (numDecoderThreads > 1) + #ifndef Z7_ST + if (mtDecoderMode) + { + WRes wres = 0; + HRESULT res = S_OK; for (i = 0; i < numEncoderThreads; i++) for (UInt32 j = 0; j < numSubDecoderThreads; j++) { CEncoderInfo &encoder = encoders[i]; - encoder.thread[j].Wait(); - if (encoder.Results[j] != S_OK) - res = encoder.Results[j]; + const WRes wres2 = encoder.thread[j]. + // Wait(); // later we can get thread times from thread in UNDER_CE + Wait_Close(); + if (wres == 0 && wres2 != 0) + wres = wres2; + const HRESULT res2 = encoder.Results[j]; + if (res == 0 && res2 != 0) + res = res2; } - RINOK(res); - #endif - - RINOK(status.Res); + if (wres != 0) + return HRESULT_FROM_WIN32(wres); + RINOK(res) + } + #endif // Z7_ST + + RINOK(status.Res) encoders[0].progressInfoSpec[0]->SetFinishTime(info); - - #ifndef _7ZIP_ST + + /* + #ifndef Z7_ST #ifdef UNDER_CE - if (numDecoderThreads > 1) + if (mtDecoderMode) for (i = 0; i < numEncoderThreads; i++) for (UInt32 j = 0; j < numSubDecoderThreads; j++) { @@ -1407,6 +2117,7 @@ static HRESULT MethodBench( } #endif #endif + */ info.UnpackSize = 0; info.PackSize = 0; @@ -1414,21 +2125,41 @@ static HRESULT MethodBench( for (i = 0; i < numEncoderThreads; i++) { - CEncoderInfo &encoder = encoders[i]; + const CEncoderInfo &encoder = encoders[i]; info.UnpackSize += encoder.kBufferSize; info.PackSize += encoder.compressedSize; } - RINOK(callback->SetDecodeResult(info, false)); - RINOK(callback->SetDecodeResult(info, true)); + // RINOK(callback->SetDecodeResult(info, false)) // why we called before 21.03 ?? + RINOK(callback->SetDecodeResult(info, true)) return S_OK; } -static inline UInt64 GetLZMAUsage(bool multiThread, UInt32 dictionary) + +static inline UInt64 GetDictSizeFromLog(unsigned dictSizeLog) +{ + /* + if (dictSizeLog < 32) + return (UInt32)1 << dictSizeLog; + else + return (UInt32)(Int32)-1; + */ + return (UInt64)1 << dictSizeLog; +} + + +// it's limit of current LZMA implementation that can be changed later +#define kLzmaMaxDictSize ((UInt32)15 << 28) + +static inline UInt64 GetLZMAUsage(bool multiThread, int btMode, UInt64 dict) { - UInt32 hs = dictionary - 1; + if (dict == 0) + dict = 1; + if (dict > kLzmaMaxDictSize) + dict = kLzmaMaxDictSize; + UInt32 hs = (UInt32)dict - 1; hs |= (hs >> 1); hs |= (hs >> 2); hs |= (hs >> 4); @@ -1438,53 +2169,158 @@ static inline UInt64 GetLZMAUsage(bool multiThread, UInt32 dictionary) if (hs > (1 << 24)) hs >>= 1; hs++; - return ((hs + (1 << 16)) + (UInt64)dictionary * 2) * 4 + (UInt64)dictionary * 3 / 2 + + hs += (1 << 16); + + const UInt32 kBlockSizeMax = (UInt32)0 - (UInt32)(1 << 16); + UInt64 blockSize = (UInt64)dict + (1 << 16) + + (multiThread ? (1 << 20) : 0); + blockSize += (blockSize >> (blockSize < ((UInt32)1 << 30) ? 1 : 2)); + if (blockSize >= kBlockSizeMax) + blockSize = kBlockSizeMax; + + UInt64 son = (UInt64)dict; + if (btMode) + son *= 2; + const UInt64 v = (hs + son) * 4 + blockSize + (1 << 20) + (multiThread ? (6 << 20) : 0); + + // printf("\nGetLZMAUsage = %d\n", (UInt32)(v >> 20)); + // printf("\nblockSize = %d\n", (UInt32)(blockSize >> 20)); + return v; } -UInt64 GetBenchMemoryUsage(UInt32 numThreads, UInt32 dictionary, bool totalBench) + +UInt64 GetBenchMemoryUsage(UInt32 numThreads, int level, UInt64 dictionary, bool totalBench) { - const UInt32 kBufferSize = dictionary; - const UInt32 kCompressedBufferSize = kBufferSize; // / 2; - bool lzmaMt = (totalBench || numThreads > 1); + const size_t kBufferSize = (size_t)dictionary + kAdditionalSize; + const UInt64 kCompressedBufferSize = GetBenchCompressedSize(kBufferSize); // / 2; + if (level < 0) + level = 5; + const int algo = (level < 5 ? 0 : 1); + const int btMode = (algo == 0 ? 0 : 1); + UInt32 numBigThreads = numThreads; - if (!totalBench && lzmaMt) - numBigThreads /= 2; + bool lzmaMt = (totalBench || (numThreads > 1 && btMode)); + if (btMode) + { + if (!totalBench && lzmaMt) + numBigThreads /= 2; + } return ((UInt64)kBufferSize + kCompressedBufferSize + - GetLZMAUsage(lzmaMt, dictionary) + (2 << 20)) * numBigThreads; + GetLZMAUsage(lzmaMt, btMode, dictionary) + (2 << 20)) * numBigThreads; } -static HRESULT CrcBig(const void *data, UInt32 size, UInt64 numIterations, +static UInt64 GetBenchMemoryUsage_Hash(UInt32 numThreads, UInt64 dictionary) +{ + // dictionary += (dictionary >> 9); // for page tables (virtual memory) + return (UInt64)(dictionary + (1 << 15)) * numThreads + (2 << 20); +} + + +// ---------- CRC and HASH ---------- + +struct CCrcInfo_Base +{ + CMidAlignedBuffer Buffer; + const Byte *Data; + size_t Size; + bool CreateLocalBuf; + UInt32 CheckSum_Res; + + CCrcInfo_Base(): CreateLocalBuf(true), CheckSum_Res(0) {} + + HRESULT Generate(const Byte *data, size_t size); + HRESULT CrcProcess(UInt64 numIterations, + const UInt32 *checkSum, IHasher *hf, + IBenchPrintCallback *callback); +}; + + +HRESULT CCrcInfo_Base::Generate(const Byte *data, size_t size) +{ + Size = size; + Data = data; + if (!data || CreateLocalBuf) + { + ALLOC_WITH_HRESULT(&Buffer, size) + Data = Buffer; + } + if (!data) + RandGen(Buffer, size); + else if (CreateLocalBuf && size != 0) + memcpy(Buffer, data, size); + return S_OK; +} + + +HRESULT CCrcInfo_Base::CrcProcess(UInt64 numIterations, const UInt32 *checkSum, IHasher *hf, IBenchPrintCallback *callback) { + MY_ALIGN(16) Byte hash[64]; - UInt64 i; - for (i = 0; i < sizeof(hash); i++) - hash[i] = 0; - for (i = 0; i < numIterations; i++) + memset(hash, 0, sizeof(hash)); + + CheckSum_Res = 0; + + const UInt32 hashSize = hf->GetDigestSize(); + if (hashSize > sizeof(hash)) + return S_FALSE; + + const Byte *buf = Data; + const size_t size = Size; + UInt32 checkSum_Prev = 0; + + UInt64 prev = 0; + UInt64 cur = 0; + + for (UInt64 i = 0; i < numIterations; i++) { - if (callback && (i & 0xFF) == 0) + hf->Init(); + size_t pos = 0; + do { - RINOK(callback->CheckBreak()); + const size_t rem = size - pos; + const UInt32 kStep = ((UInt32)1 << 31); + const UInt32 curSize = (rem < kStep) ? (UInt32)rem : kStep; + hf->Update(buf + pos, curSize); + pos += curSize; } - hf->Init(); - hf->Update(data, size); + while (pos != size); + hf->Final(hash); - UInt32 hashSize = hf->GetDigestSize(); - if (hashSize > sizeof(hash)) - return S_FALSE; UInt32 sum = 0; for (UInt32 j = 0; j < hashSize; j += 4) - sum ^= GetUi32(hash + j); - if (checkSum && sum != *checkSum) { - return S_FALSE; + sum = rotlFixed(sum, 11); + sum += GetUi32(hash + j); + } + if (checkSum) + { + if (sum != *checkSum) + return S_FALSE; + } + else + { + checkSum_Prev = sum; + checkSum = &checkSum_Prev; + } + if (callback) + { + cur += size; + if (cur - prev >= ((UInt32)1 << 30)) + { + prev = cur; + RINOK(callback->CheckBreak()) + } } } + CheckSum_Res = checkSum_Prev; return S_OK; } +extern +UInt32 g_BenchCpuFreqTemp; // we need non-static variavble to disable compiler optimization UInt32 g_BenchCpuFreqTemp = 1; #define YY1 sum += val; sum ^= val; @@ -1507,24 +2343,29 @@ static UInt32 CountCpuFreq(UInt32 sum, UInt32 num, UInt32 val) EXTERN_C_END -#ifndef _7ZIP_ST +#ifndef Z7_ST -struct CFreqInfo +struct CBaseThreadInfo { NWindows::CThread Thread; IBenchPrintCallback *Callback; HRESULT CallbackRes; - UInt32 ValRes; - UInt32 Size; - UInt64 NumIterations; - void Wait() + WRes Wait_If_Created() { - Thread.Wait(); - Thread.Close(); + if (!Thread.IsCreated()) + return 0; + return Thread.Wait_Close(); } }; +struct CFreqInfo: public CBaseThreadInfo +{ + UInt32 ValRes; + UInt32 Size; + UInt64 NumIterations; +}; + static THREAD_FUNC_DECL FreqThreadFunction(void *param) { CFreqInfo *p = (CFreqInfo *)param; @@ -1532,13 +2373,16 @@ static THREAD_FUNC_DECL FreqThreadFunction(void *param) UInt32 sum = g_BenchCpuFreqTemp; for (UInt64 k = p->NumIterations; k > 0; k--) { - p->CallbackRes = p->Callback->CheckBreak(); - if (p->CallbackRes != S_OK) - return 0; + if (p->Callback) + { + p->CallbackRes = p->Callback->CheckBreak(); + if (p->CallbackRes != S_OK) + break; + } sum = CountCpuFreq(sum, p->Size, g_BenchCpuFreqTemp); } p->ValRes = sum; - return 0; + return THREAD_FUNC_RET_ZERO; } struct CFreqThreads @@ -1546,13 +2390,21 @@ struct CFreqThreads CFreqInfo *Items; UInt32 NumThreads; - CFreqThreads(): Items(0), NumThreads(0) {} - void WaitAll() + CFreqThreads(): Items(NULL), NumThreads(0) {} + + WRes WaitAll() { + WRes wres = 0; for (UInt32 i = 0; i < NumThreads; i++) - Items[i].Wait(); + { + WRes wres2 = Items[i].Wait_If_Created(); + if (wres == 0 && wres2 != 0) + wres = wres2; + } NumThreads = 0; + return wres; } + ~CFreqThreads() { WaitAll(); @@ -1560,30 +2412,95 @@ struct CFreqThreads } }; -struct CCrcInfo -{ - NWindows::CThread Thread; - IBenchPrintCallback *Callback; - HRESULT CallbackRes; +static THREAD_FUNC_DECL CrcThreadFunction(void *param); + +struct CCrcInfo: public CBaseThreadInfo +{ const Byte *Data; - UInt32 Size; + size_t Size; UInt64 NumIterations; bool CheckSumDefined; UInt32 CheckSum; CMyComPtr<IHasher> Hasher; HRESULT Res; + UInt32 CheckSum_Res; + + #ifndef Z7_ST + NSynchronization::CManualResetEvent ReadyEvent; + UInt32 ThreadIndex; + CBenchSyncCommon *Common; + CAffinityMode AffinityMode; + #endif + + // we want to call CCrcInfo_Base::Buffer.Free() in main thread. + // so we uses non-local CCrcInfo_Base. + CCrcInfo_Base crcib; + + HRESULT CreateThread() + { + WRes res = 0; + if (!ReadyEvent.IsCreated()) + res = ReadyEvent.Create(); + if (res == 0) + res = AffinityMode.CreateThread_WithAffinity(Thread, CrcThreadFunction, this, + ThreadIndex); + return HRESULT_FROM_WIN32(res); + } #ifdef USE_ALLOCA size_t AllocaSize; #endif - void Wait() + void Process(); + + CCrcInfo(): Res(E_FAIL) {} +}; + +static const bool k_Crc_CreateLocalBuf_For_File = true; // for total BW test +// static const bool k_Crc_CreateLocalBuf_For_File = false; // for shared memory read test + +void CCrcInfo::Process() +{ + crcib.CreateLocalBuf = k_Crc_CreateLocalBuf_For_File; + // we can use additional Generate() passes to reduce some time effects for new page allocation + // for (unsigned y = 0; y < 10; y++) + Res = crcib.Generate(Data, Size); + + // if (Common) { - Thread.Wait(); - Thread.Close(); + WRes wres = ReadyEvent.Set(); + if (wres != 0) + { + if (Res == 0) + Res = HRESULT_FROM_WIN32(wres); + return; + } + if (Res != 0) + return; + + wres = Common->StartEvent.Lock(); + + if (wres != 0) + { + Res = HRESULT_FROM_WIN32(wres); + return; + } + if (Common->ExitMode) + return; } -}; + + Res = crcib.CrcProcess(NumIterations, + CheckSumDefined ? &CheckSum : NULL, Hasher, + Callback); + CheckSum_Res = crcib.CheckSum_Res; + /* + We don't want to include the time of slow CCrcInfo_Base::Buffer.Free() + to time of benchmark. So we don't free Buffer here + */ + // crcib.Buffer.Free(); +} + static THREAD_FUNC_DECL CrcThreadFunction(void *param) { @@ -1592,73 +2509,87 @@ static THREAD_FUNC_DECL CrcThreadFunction(void *param) #ifdef USE_ALLOCA alloca(p->AllocaSize); #endif - - p->Res = CrcBig(p->Data, p->Size, p->NumIterations, - p->CheckSumDefined ? &p->CheckSum : NULL, p->Hasher, - p->Callback); - return 0; + p->Process(); + return THREAD_FUNC_RET_ZERO; } + struct CCrcThreads { CCrcInfo *Items; - UInt32 NumThreads; + unsigned NumThreads; + CBenchSyncCommon Common; + bool NeedClose; + + CCrcThreads(): Items(NULL), NumThreads(0), NeedClose(false) {} + + WRes StartAndWait(bool exitMode = false); - CCrcThreads(): Items(0), NumThreads(0) {} - void WaitAll() - { - for (UInt32 i = 0; i < NumThreads; i++) - Items[i].Wait(); - NumThreads = 0; - } ~CCrcThreads() { - WaitAll(); + StartAndWait(true); delete []Items; } }; -#endif -static UInt32 CrcCalc1(const Byte *buf, UInt32 size) +WRes CCrcThreads::StartAndWait(bool exitMode) { - UInt32 crc = CRC_INIT_VAL;; - for (UInt32 i = 0; i < size; i++) - crc = CRC_UPDATE_BYTE(crc, buf[i]); - return CRC_GET_DIGEST(crc); + if (!NeedClose) + return 0; + + Common.ExitMode = exitMode; + WRes wres = Common.StartEvent.Set(); + + for (unsigned i = 0; i < NumThreads; i++) + { + WRes wres2 = Items[i].Wait_If_Created(); + if (wres == 0 && wres2 != 0) + wres = wres2; + } + NumThreads = 0; + NeedClose = false; + return wres; } -static void RandGen(Byte *buf, UInt32 size, CBaseRandomGenerator &RG) +#endif + + +static UInt32 CrcCalc1(const Byte *buf, size_t size) { - for (UInt32 i = 0; i < size; i++) - buf[i] = (Byte)RG.GetRnd(); + UInt32 crc = CRC_INIT_VAL; + for (size_t i = 0; i < size; i++) + crc = CRC_UPDATE_BYTE(crc, buf[i]); + return CRC_GET_DIGEST(crc); } -static UInt32 RandGenCrc(Byte *buf, UInt32 size, CBaseRandomGenerator &RG) +/* +static UInt32 RandGenCrc(Byte *buf, size_t size, CBaseRandomGenerator &RG) { RandGen(buf, size, RG); return CrcCalc1(buf, size); } +*/ -bool CrcInternalTest() +static bool CrcInternalTest() { - CBenchBuffer buffer; - const UInt32 kBufferSize0 = (1 << 8); - const UInt32 kBufferSize1 = (1 << 10); - const UInt32 kCheckSize = (1 << 5); - if (!buffer.Alloc(kBufferSize0 + kBufferSize1)) + CAlignedBuffer buffer; + const size_t kBufferSize0 = (1 << 8); + const size_t kBufferSize1 = (1 << 10); + const unsigned kCheckSize = (1 << 5); + buffer.Alloc(kBufferSize0 + kBufferSize1); + if (!buffer.IsAllocated()) return false; - Byte *buf = buffer.Buffer; - UInt32 i; + Byte *buf = (Byte *)buffer; + size_t i; for (i = 0; i < kBufferSize0; i++) buf[i] = (Byte)i; UInt32 crc1 = CrcCalc1(buf, kBufferSize0); if (crc1 != 0x29058C73) return false; - CBaseRandomGenerator RG; - RandGen(buf + kBufferSize0, kBufferSize1, RG); + RandGen(buf + kBufferSize0, kBufferSize1); for (i = 0; i < kBufferSize0 + kBufferSize1 - kCheckSize; i++) - for (UInt32 j = 0; j < kCheckSize; j++) + for (unsigned j = 0; j < kCheckSize; j++) if (CrcCalc1(buf + i, j) != CrcCalc(buf + i, j)) return false; return true; @@ -1668,15 +2599,29 @@ struct CBenchMethod { unsigned Weight; unsigned DictBits; - UInt32 EncComplex; - UInt32 DecComplexCompr; - UInt32 DecComplexUnc; + Int32 EncComplex; + Int32 DecComplexCompr; + Int32 DecComplexUnc; const char *Name; + // unsigned KeySize; }; +// #define USE_SW_CMPLX + +#ifdef USE_SW_CMPLX +#define CMPLX(x) ((x) * 1000) +#else +#define CMPLX(x) (x) +#endif + static const CBenchMethod g_Bench[] = { - { 40, 17, 357, 145, 20, "LZMA:x1" }, + // { 40, 17, 357, 145, 20, "LZMA:x1" }, + // { 20, 18, 360, 145, 20, "LZMA2:x1:mt2" }, + + { 20, 18, 360, 145, 20, "LZMA:x1" }, + { 20, 22, 600, 145, 20, "LZMA:x3" }, + { 80, 24, 1220, 145, 20, "LZMA:x5:mt1" }, { 80, 24, 1220, 145, 20, "LZMA:x5:mt2" }, @@ -1690,14 +2635,46 @@ static const CBenchMethod g_Bench[] = { 10, 19, 815, 122, 122, "BZip2:x5:mt2" }, { 10, 19, 2530, 122, 122, "BZip2:x7" }, + // { 10, 18, 1010, 0, 1150, "PPMDZip:x1" }, { 10, 18, 1010, 0, 1150, "PPMD:x1" }, + // { 10, 22, 1655, 0, 1830, "PPMDZip:x5" }, { 10, 22, 1655, 0, 1830, "PPMD:x5" }, - { 2, 0, 6, 0, 6, "Delta:4" }, - { 2, 0, 4, 0, 4, "BCJ" }, + // { 2, 0, -16, 0, -16, "Swap2" }, + { 2, 0, -16, 0, -16, "Swap4" }, + // { 2, 0, 3, 0, 4, "Delta:1" }, + // { 2, 0, 3, 0, 4, "Delta:2" }, + // { 2, 0, 3, 0, 4, "Delta:3" }, + { 2, 0, 3, 0, 4, "Delta:4" }, + // { 2, 0, 3, 0, 4, "Delta:8" }, + // { 2, 0, 3, 0, 4, "Delta:32" }, + + { 2, 0, 2, 0, 2, "BCJ" }, + { 2, 0, 1, 0, 1, "ARM64" }, + + // { 10, 0, 18, 0, 18, "AES128CBC:1" }, + // { 10, 0, 21, 0, 21, "AES192CBC:1" }, { 10, 0, 24, 0, 24, "AES256CBC:1" }, - { 2, 0, 8, 0, 2, "AES256CBC:2" } + + // { 10, 0, 18, 0, 18, "AES128CTR:1" }, + // { 10, 0, 21, 0, 21, "AES192CTR:1" }, + // { 10, 0, 24, 0, 24, "AES256CTR:1" }, + // { 2, 0, CMPLX(6), 0, CMPLX(1), "AES128CBC:2" }, + // { 2, 0, CMPLX(7), 0, CMPLX(1), "AES192CBC:2" }, + { 2, 0, CMPLX(8), 0, CMPLX(1), "AES256CBC:2" }, + + // { 2, 0, CMPLX(1), 0, CMPLX(1), "AES128CTR:2" }, + // { 2, 0, CMPLX(1), 0, CMPLX(1), "AES192CTR:2" }, + // { 2, 0, CMPLX(1), 0, CMPLX(1), "AES256CTR:2" }, + + // { 1, 0, CMPLX(6), 0, CMPLX(1), "AES128CBC:3" }, + // { 1, 0, CMPLX(7), 0, CMPLX(1), "AES192CBC:3" }, + { 1, 0, CMPLX(8), 0, CMPLX(1), "AES256CBC:3" } + + // { 1, 0, CMPLX(1), 0, CMPLX(1), "AES128CTR:3" }, + // { 1, 0, CMPLX(1), 0, CMPLX(1), "AES192CTR:3" }, + // { 1, 0, CMPLX(1), 0, CMPLX(1), "AES256CTR:3" }, }; struct CBenchHash @@ -1708,36 +2685,27 @@ struct CBenchHash const char *Name; }; -static const CBenchHash g_Hash[] = -{ - { 1, 1820, 0x8F8FEDAB, "CRC32:1" }, - { 10, 558, 0x8F8FEDAB, "CRC32:4" }, - { 10, 339, 0x8F8FEDAB, "CRC32:8" }, - { 10, 512, 0xDF1C17CC, "CRC64" }, - { 10, 5100, 0x2D79FF2E, "SHA256" }, - { 10, 2340, 0x4C25132B, "SHA1" }, - { 2, 5500, 0xE084E913, "BLAKE2sp" } -}; +// #define ARM_CRC_MUL 100 +#define ARM_CRC_MUL 1 -struct CTotalBenchRes -{ - // UInt64 NumIterations1; // for Usage - UInt64 NumIterations2; // for Rating / RPU +#define k_Hash_Complex_Mult 256 - UInt64 Rating; - UInt64 Usage; - UInt64 RPU; +static const CBenchHash g_Hash[] = +{ + // { 1, 1820, 0x21e207bb, "CRC32:1" }, + // { 10, 558, 0x21e207bb, "CRC32:4" }, + { 20, 339, 0x21e207bb, "CRC32:8" } , + { 2, 128 *ARM_CRC_MUL, 0x21e207bb, "CRC32:32" }, + { 2, 64 *ARM_CRC_MUL, 0x21e207bb, "CRC32:64" }, + { 10, 512, 0x41b901d1, "CRC64" }, - void Init() { /* NumIterations1 = 0; */ NumIterations2 = 0; Rating = 0; Usage = 0; RPU = 0; } - - void SetSum(const CTotalBenchRes &r1, const CTotalBenchRes &r2) - { - Rating = (r1.Rating + r2.Rating); - Usage = (r1.Usage + r2.Usage); - RPU = (r1.RPU + r2.RPU); - // NumIterations1 = (r1.NumIterations1 + r2.NumIterations1); - NumIterations2 = (r1.NumIterations2 + r2.NumIterations2); - } + { 10, 5100, 0x7913ba03, "SHA256:1" }, + { 2, CMPLX((32 * 4 + 1) * 4 + 4), 0x7913ba03, "SHA256:2" }, + + { 10, 2340, 0xff769021, "SHA1:1" }, + { 2, CMPLX((20 * 6 + 1) * 4 + 4), 0xff769021, "SHA1:2" }, + + { 2, 5500, 0x85189d02, "BLAKE2sp" } }; static void PrintNumber(IBenchPrintCallback &f, UInt64 value, unsigned size) @@ -1754,9 +2722,11 @@ static void PrintNumber(IBenchPrintCallback &f, UInt64 value, unsigned size) unsigned len = (unsigned)strlen(s + startPos); if (size > len) { - startPos -= (size - len); - if (startPos < 0) + size -= len; + if (startPos < size) startPos = 0; + else + startPos -= size; } f.Print(s + startPos); } @@ -1769,6 +2739,8 @@ static const unsigned kFieldSize_RU = 6; static const unsigned kFieldSize_Rating = 6; static const unsigned kFieldSize_EU = 5; static const unsigned kFieldSize_Effec = 5; +static const unsigned kFieldSize_CrcSpeed = 8; + static const unsigned kFieldSize_TotalSize = 4 + kFieldSize_Speed + kFieldSize_Usage + kFieldSize_RU + kFieldSize_Rating; static const unsigned kFieldSize_EUAndEffec = 2 + kFieldSize_EU + kFieldSize_Effec; @@ -1782,7 +2754,10 @@ static void PrintRating(IBenchPrintCallback &f, UInt64 rating, unsigned size) static void PrintPercents(IBenchPrintCallback &f, UInt64 val, UInt64 divider, unsigned size) { - PrintNumber(f, (val * 100 + divider / 2) / divider, size); + UInt64 v = 0; + if (divider != 0) + v = (val * 100 + divider / 2) / divider; + PrintNumber(f, v, size); } static void PrintChars(IBenchPrintCallback &f, char c, unsigned size) @@ -1798,9 +2773,14 @@ static void PrintSpaces(IBenchPrintCallback &f, unsigned size) PrintChars(f, ' ', size); } +static void PrintUsage(IBenchPrintCallback &f, UInt64 usage, unsigned size) +{ + PrintNumber(f, Benchmark_GetUsage_Percents(usage), size); +} + static void PrintResults(IBenchPrintCallback &f, UInt64 usage, UInt64 rpu, UInt64 rating, bool showFreq, UInt64 cpuFreq) { - PrintNumber(f, (usage + 5000) / 10000, kFieldSize_Usage); + PrintUsage(f, usage, kFieldSize_Usage); PrintRating(f, rpu, kFieldSize_RU); PrintRating(f, rating, kFieldSize_Rating); if (showFreq) @@ -1809,15 +2789,39 @@ static void PrintResults(IBenchPrintCallback &f, UInt64 usage, UInt64 rpu, UInt6 PrintSpaces(f, kFieldSize_EUAndEffec); else { - UInt64 ddd = cpuFreq * usage / 100; - if (ddd == 0) - ddd = 1; - PrintPercents(f, (rating * 10000), ddd, kFieldSize_EU); + PrintPercents(f, rating, cpuFreq * usage / kBenchmarkUsageMult, kFieldSize_EU); PrintPercents(f, rating, cpuFreq, kFieldSize_Effec); } } } + +void CTotalBenchRes::Generate_From_BenchInfo(const CBenchInfo &info) +{ + Speed = info.GetUnpackSizeSpeed(); + Usage = info.GetUsage(); + RPU = info.GetRatingPerUsage(Rating); +} + +void CTotalBenchRes::Mult_For_Weight(unsigned weight) +{ + NumIterations2 *= weight; + RPU *= weight; + Rating *= weight; + Usage *= weight; + Speed *= weight; +} + +void CTotalBenchRes::Update_With_Res(const CTotalBenchRes &r) +{ + Rating += r.Rating; + Usage += r.Usage; + RPU += r.RPU; + Speed += r.Speed; + // NumIterations1 = (r1.NumIterations1 + r2.NumIterations1); + NumIterations2 += r.NumIterations2; +} + static void PrintResults(IBenchPrintCallback *f, const CBenchInfo &info, unsigned weight, @@ -1825,39 +2829,126 @@ static void PrintResults(IBenchPrintCallback *f, bool showFreq, UInt64 cpuFreq, CTotalBenchRes *res) { - UInt64 speed = info.GetSpeed(info.UnpackSize * info.NumIterations); + CTotalBenchRes t; + t.Rating = rating; + t.NumIterations2 = 1; + t.Generate_From_BenchInfo(info); + if (f) { - if (speed != 0) - PrintNumber(*f, speed / 1024, kFieldSize_Speed); + if (t.Speed != 0) + PrintNumber(*f, t.Speed / 1024, kFieldSize_Speed); else PrintSpaces(*f, 1 + kFieldSize_Speed); } - UInt64 usage = info.GetUsage(); - UInt64 rpu = info.GetRatingPerUsage(rating); if (f) { - PrintResults(*f, usage, rpu, rating, showFreq, cpuFreq); + PrintResults(*f, t.Usage, t.RPU, rating, showFreq, cpuFreq); } if (res) { // res->NumIterations1++; - res->NumIterations2 += weight; - res->RPU += (rpu * weight); - res->Rating += (rating * weight); - res->Usage += (usage * weight); + t.Mult_For_Weight(weight); + res->Update_With_Res(t); } } -static void PrintTotals(IBenchPrintCallback &f, bool showFreq, UInt64 cpuFreq, const CTotalBenchRes &res) +static void PrintTotals(IBenchPrintCallback &f, + bool showFreq, UInt64 cpuFreq, bool showSpeed, const CTotalBenchRes &res) { - PrintSpaces(f, 1 + kFieldSize_Speed); + const UInt64 numIterations2 = res.NumIterations2 ? res.NumIterations2 : 1; + const UInt64 speed = res.Speed / numIterations2; + if (showSpeed && speed != 0) + PrintNumber(f, speed / 1024, kFieldSize_Speed); + else + PrintSpaces(f, 1 + kFieldSize_Speed); + + // PrintSpaces(f, 1 + kFieldSize_Speed); // UInt64 numIterations1 = res.NumIterations1; if (numIterations1 == 0) numIterations1 = 1; - UInt64 numIterations2 = res.NumIterations2; if (numIterations2 == 0) numIterations2 = 1; PrintResults(f, res.Usage / numIterations2, res.RPU / numIterations2, res.Rating / numIterations2, showFreq, cpuFreq); } + +static void PrintHex(AString &s, UInt64 v) +{ + char temp[32]; + ConvertUInt64ToHex(v, temp); + s += temp; +} + +AString GetProcessThreadsInfo(const NSystem::CProcessAffinity &ti) +{ + AString s; + // s.Add_UInt32(ti.numProcessThreads); + unsigned numSysThreads = ti.GetNumSystemThreads(); + if (ti.GetNumProcessThreads() != numSysThreads) + { + // if (ti.numProcessThreads != ti.numSysThreads) + { + s += " / "; + s.Add_UInt32(numSysThreads); + } + s += " : "; + #ifdef _WIN32 + PrintHex(s, ti.processAffinityMask); + s += " / "; + PrintHex(s, ti.systemAffinityMask); + #else + unsigned i = (numSysThreads + 3) & ~(unsigned)3; + if (i == 0) + i = 4; + for (; i >= 4; ) + { + i -= 4; + unsigned val = 0; + for (unsigned k = 0; k < 4; k++) + { + const unsigned bit = (ti.IsCpuSet(i + k) ? 1 : 0); + val += (bit << k); + } + PrintHex(s, val); + } + #endif + } + return s; +} + + +#ifdef Z7_LARGE_PAGES + +#ifdef _WIN32 +extern bool g_LargePagesMode; +extern "C" +{ + extern SIZE_T g_LargePageSize; +} +#endif + +void Add_LargePages_String(AString &s) +{ + #ifdef _WIN32 + if (g_LargePagesMode || g_LargePageSize != 0) + { + s.Add_OptSpaced("(LP-"); + PrintSize_KMGT_Or_Hex(s, g_LargePageSize); + #ifdef MY_CPU_X86_OR_AMD64 + if (CPU_IsSupported_PageGB()) + s += "-1G"; + #endif + if (!g_LargePagesMode) + s += "-NA"; + s += ")"; + } + #else + s += ""; + #endif +} + +#endif + + + static void PrintRequirements(IBenchPrintCallback &f, const char *sizeString, bool size_Defined, UInt64 size, const char *threadsString, UInt32 numThreads) { @@ -1867,36 +2958,51 @@ static void PrintRequirements(IBenchPrintCallback &f, const char *sizeString, PrintNumber(f, (size >> 20), 6); else f.Print(" ?"); - f.Print(" MB, # "); + f.Print(" MB"); + + #ifdef Z7_LARGE_PAGES + { + AString s; + Add_LargePages_String(s); + f.Print(s); + } + #endif + + f.Print(", # "); f.Print(threadsString); PrintNumber(f, numThreads, 3); - f.NewLine(); } -struct CBenchCallbackToPrint: public IBenchCallback -{ - CBenchProps BenchProps; - CTotalBenchRes EncodeRes; - CTotalBenchRes DecodeRes; - IBenchPrintCallback *_file; - UInt32 DictSize; - bool Use2Columns; - unsigned NameFieldSize; +struct CBenchCallbackToPrint Z7_final: public IBenchCallback +{ + bool NeedPrint; + bool Use2Columns; bool ShowFreq; - UInt64 CpuFreq; + unsigned NameFieldSize; unsigned EncodeWeight; unsigned DecodeWeight; + UInt64 CpuFreq; + UInt64 DictSize; + + IBenchPrintCallback *_file; + CBenchProps BenchProps; + CTotalBenchRes EncodeRes; + CTotalBenchRes DecodeRes; + + CBenchInfo BenchInfo_Results[2]; + CBenchCallbackToPrint(): + NeedPrint(true), Use2Columns(false), - NameFieldSize(0), ShowFreq(false), - CpuFreq(0), + NameFieldSize(0), EncodeWeight(1), - DecodeWeight(1) + DecodeWeight(1), + CpuFreq(0) {} void Init() { EncodeRes.Init(); DecodeRes.Init(); } @@ -1904,8 +3010,8 @@ struct CBenchCallbackToPrint: public IBenchCallback void NewLine(); HRESULT SetFreq(bool showFreq, UInt64 cpuFreq); - HRESULT SetEncodeResult(const CBenchInfo &info, bool final); - HRESULT SetDecodeResult(const CBenchInfo &info, bool final); + HRESULT SetEncodeResult(const CBenchInfo &info, bool final) Z7_override; + HRESULT SetDecodeResult(const CBenchInfo &info, bool final) Z7_override; }; HRESULT CBenchCallbackToPrint::SetFreq(bool showFreq, UInt64 cpuFreq) @@ -1917,10 +3023,13 @@ HRESULT CBenchCallbackToPrint::SetFreq(bool showFreq, UInt64 cpuFreq) HRESULT CBenchCallbackToPrint::SetEncodeResult(const CBenchInfo &info, bool final) { - RINOK(_file->CheckBreak()); + RINOK(_file->CheckBreak()) + if (final) + BenchInfo_Results[0] = info; if (final) + if (NeedPrint) { - UInt64 rating = BenchProps.GetCompressRating(DictSize, info.GlobalTime, info.GlobalFreq, info.UnpackSize * info.NumIterations); + const UInt64 rating = BenchProps.GetRating_Enc(DictSize, info.GlobalTime, info.GlobalFreq, info.UnpackSize * info.NumIterations); PrintResults(_file, info, EncodeWeight, rating, ShowFreq, CpuFreq, &EncodeRes); @@ -1930,14 +3039,17 @@ HRESULT CBenchCallbackToPrint::SetEncodeResult(const CBenchInfo &info, bool fina return S_OK; } -static const char *kSep = " | "; +static const char * const kSep = " | "; HRESULT CBenchCallbackToPrint::SetDecodeResult(const CBenchInfo &info, bool final) { - RINOK(_file->CheckBreak()); + RINOK(_file->CheckBreak()) if (final) + BenchInfo_Results[1] = info; + if (final) + if (NeedPrint) { - UInt64 rating = BenchProps.GetDecompressRating(info.GlobalTime, info.GlobalFreq, info.UnpackSize, info.PackSize, info.NumIterations); + const UInt64 rating = BenchProps.GetRating_Dec(info.GlobalTime, info.GlobalFreq, info.UnpackSize, info.PackSize, info.NumIterations); if (Use2Columns) _file->Print(kSep); else @@ -1963,35 +3075,58 @@ void CBenchCallbackToPrint::NewLine() _file->NewLine(); } -void PrintLeft(IBenchPrintCallback &f, const char *s, unsigned size) +static void PrintLeft(IBenchPrintCallback &f, const char *s, unsigned size) { f.Print(s); - int numSpaces = size - MyStringLen(s); + int numSpaces = (int)size - (int)MyStringLen(s); if (numSpaces > 0) - PrintSpaces(f, numSpaces); + PrintSpaces(f, (unsigned)numSpaces); } -void PrintRight(IBenchPrintCallback &f, const char *s, unsigned size) +static void PrintRight(IBenchPrintCallback &f, const char *s, unsigned size) { - int numSpaces = size - MyStringLen(s); + int numSpaces = (int)size - (int)MyStringLen(s); if (numSpaces > 0) - PrintSpaces(f, numSpaces); + PrintSpaces(f, (unsigned)numSpaces); f.Print(s); } + +static bool DoesWildcardMatchName_NoCase(const AString &mask, const char *name) +{ + UString wildc = GetUnicodeString(mask); + UString bname = GetUnicodeString(name); + wildc.MakeLower_Ascii(); + bname.MakeLower_Ascii(); + return DoesWildcardMatchName(wildc, bname); +} + + static HRESULT TotalBench( DECL_EXTERNAL_CODECS_LOC_VARS + const COneMethodInfo &methodMask, UInt64 complexInCommands, + #ifndef Z7_ST UInt32 numThreads, + const CAffinityMode *affinityMode, + #endif bool forceUnpackSize, size_t unpackSize, const Byte *fileData, IBenchPrintCallback *printCallback, CBenchCallbackToPrint *callback) { - for (unsigned i = 0; i < ARRAY_SIZE(g_Bench); i++) + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_Bench); i++) { const CBenchMethod &bench = g_Bench[i]; + if (!DoesWildcardMatchName_NoCase(methodMask.MethodName, bench.Name)) + continue; PrintLeft(*callback->_file, bench.Name, kFieldSize_Name); + { + unsigned keySize = 32; + if (IsString1PrefixedByString2(bench.Name, "AES128")) keySize = 16; + else if (IsString1PrefixedByString2(bench.Name, "AES192")) keySize = 24; + callback->BenchProps.KeySize = keySize; + } callback->BenchProps.DecComplexUnc = bench.DecComplexUnc; callback->BenchProps.DecComplexCompr = bench.DecComplexCompr; callback->BenchProps.EncComplex = bench.EncComplex; @@ -1999,7 +3134,7 @@ static HRESULT TotalBench( COneMethodInfo method; NCOM::CPropVariant propVariant; propVariant = bench.Name; - RINOK(method.ParseMethodFromPROPVARIANT(UString(), propVariant)); + RINOK(method.ParseMethodFromPROPVARIANT(UString(), propVariant)) size_t unpackSize2 = unpackSize; if (!forceUnpackSize && bench.DictBits == 0) @@ -2008,10 +3143,13 @@ static HRESULT TotalBench( callback->EncodeWeight = bench.Weight; callback->DecodeWeight = bench.Weight; - HRESULT res = MethodBench( + const HRESULT res = MethodBench( EXTERNAL_CODECS_LOC_VARS complexInCommands, - false, numThreads, method, + #ifndef Z7_ST + false, numThreads, affinityMode, + #endif + method, unpackSize2, fileData, bench.DictBits, printCallback, callback, &callback->BenchProps); @@ -2025,7 +3163,7 @@ static HRESULT TotalBench( } else { - RINOK(res); + RINOK(res) } callback->NewLine(); @@ -2034,38 +3172,67 @@ static HRESULT TotalBench( } -static HRESULT FreqBench( - UInt64 complexInCommands, - UInt32 numThreads, - IBenchPrintCallback *_file, - bool showFreq, - UInt64 specifiedFreq, - UInt64 &cpuFreq, - UInt32 &res) +struct CFreqBench +{ + // in: + UInt64 complexInCommands; + UInt32 numThreads; + bool showFreq; + UInt64 specifiedFreq; + + // out: + UInt64 CpuFreqRes; + UInt64 UsageRes; + UInt32 res; + + CFreqBench() + {} + + HRESULT FreqBench(IBenchPrintCallback *_file + #ifndef Z7_ST + , const CAffinityMode *affinityMode + #endif + ); +}; + + +HRESULT CFreqBench::FreqBench(IBenchPrintCallback *_file + #ifndef Z7_ST + , const CAffinityMode *affinityMode + #endif + ) { res = 0; - cpuFreq = 0; + CpuFreqRes = 0; + UsageRes = 0; - UInt32 bufferSize = 1 << 20; - UInt32 complexity = kNumFreqCommands; if (numThreads == 0) numThreads = 1; - #ifdef _7ZIP_ST + #ifdef Z7_ST numThreads = 1; #endif - UInt32 bsize = (bufferSize == 0 ? 1 : bufferSize); - UInt64 numIterations = complexInCommands / complexity / bsize; - if (numIterations == 0) + const UInt32 complexity = kNumFreqCommands; + UInt64 numIterations = complexInCommands / complexity; + UInt32 numIterations2 = 1 << 30; + if (numIterations > numIterations2) + numIterations /= numIterations2; + else + { + numIterations2 = (UInt32)numIterations; numIterations = 1; + } CBenchInfoCalc progressInfoSpec; - #ifndef _7ZIP_ST - CFreqThreads threads; - if (numThreads > 1) + #ifndef Z7_ST + + bool mtMode = (numThreads > 1) || affinityMode->NeedAffinity(); + + if (mtMode) { + CFreqThreads threads; threads.Items = new CFreqInfo[numThreads]; UInt32 i; for (i = 0; i < numThreads; i++) @@ -2074,19 +3241,25 @@ static HRESULT FreqBench( info.Callback = _file; info.CallbackRes = S_OK; info.NumIterations = numIterations; - info.Size = bufferSize; + info.Size = numIterations2; } progressInfoSpec.SetStartTime(); for (i = 0; i < numThreads; i++) { + // Sleep(10); CFreqInfo &info = threads.Items[i]; - RINOK(info.Thread.Create(FreqThreadFunction, &info)); - threads.NumThreads++; + WRes wres = affinityMode->CreateThread_WithAffinity(info.Thread, FreqThreadFunction, &info, i); + if (info.Thread.IsCreated()) + threads.NumThreads++; + if (wres != 0) + return HRESULT_FROM_WIN32(wres); } - threads.WaitAll(); + WRes wres = threads.WaitAll(); + if (wres != 0) + return HRESULT_FROM_WIN32(wres); for (i = 0; i < numThreads; i++) { - RINOK(threads.Items[i].CallbackRes); + RINOK(threads.Items[i].CallbackRes) } } else @@ -2096,11 +3269,20 @@ static HRESULT FreqBench( UInt32 sum = g_BenchCpuFreqTemp; for (UInt64 k = numIterations; k > 0; k--) { - RINOK(_file->CheckBreak()); - sum = CountCpuFreq(sum, bufferSize, g_BenchCpuFreqTemp); + sum = CountCpuFreq(sum, numIterations2, g_BenchCpuFreqTemp); + if (_file) + { + RINOK(_file->CheckBreak()) + } } res += sum; } + + if (res == 0x12345678) + if (_file) + { + RINOK(_file->CheckBreak()) + } CBenchInfo info; progressInfoSpec.SetFinishTime(info); @@ -2109,18 +3291,18 @@ static HRESULT FreqBench( info.PackSize = 0; info.NumIterations = 1; + const UInt64 numCommands = (UInt64)numIterations * numIterations2 * numThreads * complexity; + const UInt64 rating = info.GetSpeed(numCommands); + CpuFreqRes = rating / numThreads; + UsageRes = info.GetUsage(); + if (_file) { - { - UInt64 numCommands = (UInt64)numIterations * bufferSize * numThreads * complexity; - UInt64 rating = info.GetSpeed(numCommands); - cpuFreq = rating / numThreads; - PrintResults(_file, info, + PrintResults(_file, info, 0, // weight rating, - showFreq, showFreq ? (specifiedFreq != 0 ? specifiedFreq : cpuFreq) : 0, NULL); - } - RINOK(_file->CheckBreak()); + showFreq, showFreq ? (specifiedFreq != 0 ? specifiedFreq : CpuFreqRes) : 0, NULL); + RINOK(_file->CheckBreak()) } return S_OK; @@ -2131,23 +3313,32 @@ static HRESULT FreqBench( static HRESULT CrcBench( DECL_EXTERNAL_CODECS_LOC_VARS UInt64 complexInCommands, - UInt32 numThreads, UInt32 bufferSize, + UInt32 numThreads, + const size_t bufferSize, + const Byte *fileData, + UInt64 &speed, + UInt64 &usage, + UInt32 complexity, unsigned benchWeight, const UInt32 *checkSum, const COneMethodInfo &method, IBenchPrintCallback *_file, + #ifndef Z7_ST + const CAffinityMode *affinityMode, + #endif + bool showRating, CTotalBenchRes *encodeRes, bool showFreq, UInt64 cpuFreq) { if (numThreads == 0) numThreads = 1; - #ifdef _7ZIP_ST + #ifdef Z7_ST numThreads = 1; #endif - AString methodName = method.MethodName; + const AString &methodName = method.MethodName; // methodName.RemoveChar(L'-'); CMethodId hashID; if (!FindHashMethod( @@ -2155,98 +3346,131 @@ static HRESULT CrcBench( methodName, hashID)) return E_NOTIMPL; - CBenchBuffer buffer; - size_t totalSize = (size_t)bufferSize * numThreads; - if (totalSize / numThreads != bufferSize) - return E_OUTOFMEMORY; - if (!buffer.Alloc(totalSize)) - return E_OUTOFMEMORY; + /* + // if will generate random data in each thread, instead of global data + CMidAlignedBuffer buffer; + if (!fileData) + { + ALLOC_WITH_HRESULT(&buffer, bufferSize) + RandGen(buffer, bufferSize); + fileData = buffer; + } + */ - Byte *buf = buffer.Buffer; - CBaseRandomGenerator RG; - UInt32 bsize = (bufferSize == 0 ? 1 : bufferSize); - UInt64 numIterations = complexInCommands * 256 / complexity / bsize; + const size_t bsize = (bufferSize == 0 ? 1 : bufferSize); + UInt64 numIterations = complexInCommands * k_Hash_Complex_Mult / complexity / bsize; if (numIterations == 0) numIterations = 1; CBenchInfoCalc progressInfoSpec; + CBenchInfo info; + + #ifndef Z7_ST + bool mtEncMode = (numThreads > 1) || affinityMode->NeedAffinity(); - #ifndef _7ZIP_ST - CCrcThreads threads; - if (numThreads > 1) + if (mtEncMode) { + CCrcThreads threads; threads.Items = new CCrcInfo[numThreads]; - + { + WRes wres = threads.Common.StartEvent.Create(); + if (wres != 0) + return HRESULT_FROM_WIN32(wres); + threads.NeedClose = true; + } + UInt32 i; for (i = 0; i < numThreads; i++) { - CCrcInfo &info = threads.Items[i]; + CCrcInfo &ci = threads.Items[i]; AString name; - RINOK(CreateHasher(EXTERNAL_CODECS_LOC_VARS hashID, name, info.Hasher)); - if (!info.Hasher) + RINOK(CreateHasher(EXTERNAL_CODECS_LOC_VARS hashID, name, ci.Hasher)) + if (!ci.Hasher) return E_NOTIMPL; CMyComPtr<ICompressSetCoderProperties> scp; - info.Hasher.QueryInterface(IID_ICompressSetCoderProperties, &scp); + ci.Hasher.QueryInterface(IID_ICompressSetCoderProperties, &scp); if (scp) { - UInt64 reduceSize = 1; - RINOK(method.SetCoderProps(scp, &reduceSize)); + RINOK(method.SetCoderProps(scp)) } - Byte *data = buf + (size_t)bufferSize * i; - info.Callback = _file; - info.Data = data; - info.NumIterations = numIterations; - info.Size = bufferSize; - /* info.Crc = */ RandGenCrc(data, bufferSize, RG); - info.CheckSumDefined = false; + ci.Callback = _file; + ci.Data = fileData; + ci.NumIterations = numIterations; + ci.Size = bufferSize; + ci.CheckSumDefined = false; if (checkSum) { - info.CheckSum = *checkSum; - info.CheckSumDefined = (checkSum && (i == 0)); + ci.CheckSum = *checkSum; + ci.CheckSumDefined = true; } #ifdef USE_ALLOCA - info.AllocaSize = (i * 16 * 21) & 0x7FF; + ci.AllocaSize = (i * 16 * 21) & 0x7FF; #endif } - progressInfoSpec.SetStartTime(); + for (i = 0; i < numThreads; i++) + { + CCrcInfo &ci = threads.Items[i]; + ci.ThreadIndex = i; + ci.Common = &threads.Common; + ci.AffinityMode = *affinityMode; + HRESULT hres = ci.CreateThread(); + if (ci.Thread.IsCreated()) + threads.NumThreads++; + if (hres != 0) + return hres; + } for (i = 0; i < numThreads; i++) { - CCrcInfo &info = threads.Items[i]; - RINOK(info.Thread.Create(CrcThreadFunction, &info)); - threads.NumThreads++; + CCrcInfo &ci = threads.Items[i]; + WRes wres = ci.ReadyEvent.Lock(); + if (wres != 0) + return HRESULT_FROM_WIN32(wres); + RINOK(ci.Res) } - threads.WaitAll(); + + progressInfoSpec.SetStartTime(); + + WRes wres = threads.StartAndWait(); + if (wres != 0) + return HRESULT_FROM_WIN32(wres); + + progressInfoSpec.SetFinishTime(info); + for (i = 0; i < numThreads; i++) { - RINOK(threads.Items[i].Res); + RINOK(threads.Items[i].Res) + if (i != 0) + if (threads.Items[i].CheckSum_Res != + threads.Items[i - 1].CheckSum_Res) + return S_FALSE; } } else #endif { - /* UInt32 crc = */ RandGenCrc(buf, bufferSize, RG); - progressInfoSpec.SetStartTime(); CMyComPtr<IHasher> hasher; AString name; - RINOK(CreateHasher(EXTERNAL_CODECS_LOC_VARS hashID, name, hasher)); + RINOK(CreateHasher(EXTERNAL_CODECS_LOC_VARS hashID, name, hasher)) if (!hasher) return E_NOTIMPL; CMyComPtr<ICompressSetCoderProperties> scp; hasher.QueryInterface(IID_ICompressSetCoderProperties, &scp); if (scp) { - UInt64 reduceSize = 1; - RINOK(method.SetCoderProps(scp, &reduceSize)); + RINOK(method.SetCoderProps(scp)) } - RINOK(CrcBig(buf, bufferSize, numIterations, checkSum, hasher, _file)); + CCrcInfo_Base crcib; + crcib.CreateLocalBuf = false; + RINOK(crcib.Generate(fileData, bufferSize)) + progressInfoSpec.SetStartTime(); + RINOK(crcib.CrcProcess(numIterations, checkSum, hasher, _file)) + progressInfoSpec.SetFinishTime(info); } - CBenchInfo info; - progressInfoSpec.SetFinishTime(info); UInt64 unpSize = numIterations * bufferSize; UInt64 unpSizeThreads = unpSize * numThreads; @@ -2256,32 +3480,47 @@ static HRESULT CrcBench( if (_file) { + if (showRating) { - UInt64 numCommands = unpSizeThreads * complexity / 256; - UInt64 rating = info.GetSpeed(numCommands); + UInt64 unpSizeThreads2 = unpSizeThreads; + if (unpSizeThreads2 == 0) + unpSizeThreads2 = numIterations * 1 * numThreads; + const UInt64 numCommands = unpSizeThreads2 * complexity / 256; + const UInt64 rating = info.GetSpeed(numCommands); PrintResults(_file, info, benchWeight, rating, showFreq, cpuFreq, encodeRes); } - RINOK(_file->CheckBreak()); + RINOK(_file->CheckBreak()) } speed = info.GetSpeed(unpSizeThreads); + usage = info.GetUsage(); return S_OK; } + + static HRESULT TotalBench_Hash( DECL_EXTERNAL_CODECS_LOC_VARS + const COneMethodInfo &methodMask, UInt64 complexInCommands, - UInt32 numThreads, UInt32 bufSize, + UInt32 numThreads, + size_t bufSize, + const Byte *fileData, IBenchPrintCallback *printCallback, CBenchCallbackToPrint *callback, + #ifndef Z7_ST + const CAffinityMode *affinityMode, + #endif CTotalBenchRes *encodeRes, bool showFreq, UInt64 cpuFreq) { - for (unsigned i = 0; i < ARRAY_SIZE(g_Hash); i++) + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_Hash); i++) { const CBenchHash &bench = g_Hash[i]; + if (!DoesWildcardMatchName_NoCase(methodMask.MethodName, bench.Name)) + continue; PrintLeft(*callback->_file, bench.Name, kFieldSize_Name); // callback->BenchProps.DecComplexUnc = bench.DecComplexUnc; // callback->BenchProps.DecComplexCompr = bench.DecComplexCompr; @@ -2290,24 +3529,31 @@ static HRESULT TotalBench_Hash( COneMethodInfo method; NCOM::CPropVariant propVariant; propVariant = bench.Name; - RINOK(method.ParseMethodFromPROPVARIANT(UString(), propVariant)); + RINOK(method.ParseMethodFromPROPVARIANT(UString(), propVariant)) - UInt64 speed; - HRESULT res = CrcBench( + UInt64 speed, usage; + + const HRESULT res = CrcBench( EXTERNAL_CODECS_LOC_VARS complexInCommands, - numThreads, bufSize, - speed, + numThreads, bufSize, fileData, + speed, usage, bench.Complex, bench.Weight, - &bench.CheckSum, method, - printCallback, encodeRes, showFreq, cpuFreq); + (!fileData && bufSize == (1 << kNumHashDictBits)) ? &bench.CheckSum : NULL, + method, + printCallback, + #ifndef Z7_ST + affinityMode, + #endif + true, // showRating + encodeRes, showFreq, cpuFreq); if (res == E_NOTIMPL) { // callback->Print(" ---"); } else { - RINOK(res); + RINOK(res) } callback->NewLine(); } @@ -2317,7 +3563,8 @@ static HRESULT TotalBench_Hash( struct CTempValues { UInt64 *Values; - CTempValues(UInt32 num) { Values = new UInt64[num]; } + CTempValues(): Values(NULL) {} + void Alloc(UInt32 num) { Values = new UInt64[num]; } ~CTempValues() { delete []Values; } }; @@ -2333,110 +3580,41 @@ static void ParseNumberString(const UString &s, NCOM::CPropVariant &prop) prop = result; } -static UInt32 GetNumThreadsNext(unsigned i, UInt32 numThreads) -{ - if (i < 2) - return i + 1; - i -= 1; - UInt32 num = (UInt32)(2 + (i & 1)) << (i >> 1); - return (num <= numThreads) ? num : numThreads; -} static bool AreSameMethodNames(const char *fullName, const char *shortName) { - for (;;) - { - char c2 = *shortName++; - if (c2 == 0) - return true; - char c1 = *fullName++; - if (MyCharLower_Ascii(c1) != MyCharLower_Ascii(c2)) - return false; - } + return StringsAreEqualNoCase_Ascii(fullName, shortName); } -#ifdef MY_CPU_X86_OR_AMD64 -static void PrintCpuChars(AString &s, UInt32 v) -{ - for (int j = 0; j < 4; j++) - { - Byte b = (Byte)(v & 0xFF); - v >>= 8; - if (b == 0) - break; - s += (char)b; - } -} -static void x86cpuid_to_String(const Cx86cpuid &c, AString &s) +static void Print_Usage_and_Threads(IBenchPrintCallback &f, UInt64 usage, UInt32 threads) { - s.Empty(); - - UInt32 maxFunc2 = 0; - UInt32 t[3]; - - MyCPUID(0x80000000, &maxFunc2, &t[0], &t[1], &t[2]); - - bool fullNameIsAvail = (maxFunc2 >= 0x80000004); - - if (!fullNameIsAvail) - { - for (int i = 0; i < 3; i++) - PrintCpuChars(s, c.vendor[i]); - } - else - { - for (int i = 0; i < 3; i++) - { - UInt32 d[4] = { 0 }; - MyCPUID(0x80000002 + i, &d[0], &d[1], &d[2], &d[3]); - for (int j = 0; j < 4; j++) - PrintCpuChars(s, d[j]); - } - } - - s.Add_Space_if_NotEmpty(); - { - char temp[32]; - ConvertUInt32ToHex(c.ver, temp); - s += '('; - s += temp; - s += ')'; - } + PrintRequirements(f, "usage:", true, usage, "Benchmark threads: ", threads); } -#endif - -void GetCpuName(AString &s) +static void Print_Delimiter(IBenchPrintCallback &f) { - s.Empty(); + f.Print(" |"); +} - #ifdef MY_CPU_X86_OR_AMD64 - { - Cx86cpuid cpuid; - if (x86cpuid_CheckAndRead(&cpuid)) - { - x86cpuid_to_String(cpuid, s); - return; - } - #ifdef MY_CPU_AMD64 - s = "x64"; - #else - s = "x86"; - #endif - } - #else - - #ifdef MY_CPU_LE - s = "LE"; - #elif defined(MY_CPU_BE) - s = "BE"; - #endif +static void Print_Pow(IBenchPrintCallback &f, unsigned pow) +{ + char s[16]; + ConvertUInt32ToString(pow, s); + unsigned pos = MyStringLen(s); + s[pos++] = ':'; + s[pos] = 0; + PrintLeft(f, s, kFieldSize_SmallName); // 4 +} - #endif +static void Bench_BW_Print_Usage_Speed(IBenchPrintCallback &f, + UInt64 usage, UInt64 speed) +{ + PrintUsage(f, usage, kFieldSize_Usage); + PrintNumber(f, speed / 1000000, kFieldSize_CrcSpeed); } @@ -2446,38 +3624,87 @@ HRESULT Bench( IBenchCallback *benchCallback, const CObjectVector<CProperty> &props, UInt32 numIterations, - bool multiDict) + bool multiDict, + IBenchFreqCallback *freqCallback) { if (!CrcInternalTest()) - return S_FALSE; + return E_FAIL; UInt32 numCPUs = 1; UInt64 ramSize = (UInt64)(sizeof(size_t)) << 29; - #ifndef _7ZIP_ST - numCPUs = NSystem::GetNumberOfProcessors(); + NSystem::CProcessAffinity threadsInfo; + threadsInfo.InitST(); + + #ifndef Z7_ST + + if (threadsInfo.Get() && threadsInfo.GetNumProcessThreads() != 0) + numCPUs = threadsInfo.GetNumProcessThreads(); + else + numCPUs = NSystem::GetNumberOfProcessors(); + #endif + + // numCPUs = 24; + /* + { + DWORD_PTR mask = (1 << 0); + DWORD_PTR old = SetThreadAffinityMask(GetCurrentThread(), mask); + old = old; + DWORD_PTR old2 = SetThreadAffinityMask(GetCurrentThread(), mask); + old2 = old2; + return 0; + } + */ bool ramSize_Defined = NSystem::GetRamSize(ramSize); UInt32 numThreadsSpecified = numCPUs; - - UInt32 testTime = kComplexInSeconds; - + bool needSetComplexity = false; + UInt32 testTimeMs = kComplexInMs; + UInt32 startDicLog = 22; + bool startDicLog_Defined = false; UInt64 specifiedFreq = 0; - bool multiThreadTests = false; + UInt64 complexInCommands = kComplexInCommands; + UInt32 numThreads_Start = 1; + + #ifndef Z7_ST + CAffinityMode affinityMode; + #endif + COneMethodInfo method; - CBenchBuffer fileDataBuffer; + CMidAlignedBuffer fileDataBuffer; + bool use_fileData = false; + bool isFixedDict = false; { unsigned i; + + if (printCallback) + { + for (i = 0; i < props.Size(); i++) + { + const CProperty &property = props[i]; + printCallback->Print(" "); + printCallback->Print(GetAnsiString(property.Name)); + if (!property.Value.IsEmpty()) + { + printCallback->Print("="); + printCallback->Print(GetAnsiString(property.Value)); + } + } + if (!props.IsEmpty()) + printCallback->NewLine(); + } + + for (i = 0; i < props.Size(); i++) { const CProperty &property = props[i]; - UString name = property.Name; + UString name (property.Name); name.MakeLower_Ascii(); if (name.IsEqualTo("file")) @@ -2485,36 +3712,38 @@ HRESULT Bench( if (property.Value.IsEmpty()) return E_INVALIDARG; - #ifdef USE_WIN_FILE - NFile::NIO::CInFile file; if (!file.Open(us2fs(property.Value))) - return E_INVALIDARG; - UInt64 len; - if (!file.GetLength(len)) - return E_FAIL; - if (len >= ((UInt32)1 << 31) || len == 0) - return E_INVALIDARG; - if (!fileDataBuffer.Alloc((size_t)len)) - return E_OUTOFMEMORY; - UInt32 processedSize; - file.Read(fileDataBuffer.Buffer, (UInt32)len, processedSize); - if (processedSize != len) - return E_FAIL; - if (printCallback) + return GetLastError_noZero_HRESULT(); + size_t len; { - printCallback->Print("file size ="); - // printCallback->Print(GetOemString(property.Value)); - PrintNumber(*printCallback, len, 0); - printCallback->NewLine(); + UInt64 len64; + if (!file.GetLength(len64)) + return GetLastError_noZero_HRESULT(); + if (printCallback) + { + printCallback->Print("file size ="); + PrintNumber(*printCallback, len64, 0); + printCallback->NewLine(); + } + len = (size_t)len64; + if (len != len64) + return E_INVALIDARG; } - continue; - #else + // (len == 0) is allowed. Also it's allowed if Alloc(0) returns NULL here - return E_NOTIMPL; + ALLOC_WITH_HRESULT(&fileDataBuffer, len) + use_fileData = true; - #endif + { + size_t processed; + if (!file.ReadFull((Byte *)fileDataBuffer, len, processed)) + return GetLastError_noZero_HRESULT(); + if (processed != len) + return E_FAIL; + } + continue; } NCOM::CPropVariant propVariant; @@ -2523,14 +3752,65 @@ HRESULT Bench( if (name.IsEqualTo("time")) { - RINOK(ParsePropToUInt32(L"", propVariant, testTime)); + RINOK(ParsePropToUInt32(UString(), propVariant, testTimeMs)) + needSetComplexity = true; + testTimeMs *= 1000; continue; } - + + if (name.IsEqualTo("timems")) + { + RINOK(ParsePropToUInt32(UString(), propVariant, testTimeMs)) + needSetComplexity = true; + continue; + } + + if (name.IsEqualTo("tic")) + { + UInt32 v; + RINOK(ParsePropToUInt32(UString(), propVariant, v)) + if (v >= 64) + return E_INVALIDARG; + complexInCommands = (UInt64)1 << v; + continue; + } + + const bool isCurrent_fixedDict = name.IsEqualTo("df"); + if (isCurrent_fixedDict) + isFixedDict = true; + if (isCurrent_fixedDict || name.IsEqualTo("ds")) + { + RINOK(ParsePropToUInt32(UString(), propVariant, startDicLog)) + if (startDicLog > 32) + return E_INVALIDARG; + startDicLog_Defined = true; + continue; + } + + if (name.IsEqualTo("mts")) + { + RINOK(ParsePropToUInt32(UString(), propVariant, numThreads_Start)) + continue; + } + + if (name.IsEqualTo("af")) + { + UInt32 bundle; + RINOK(ParsePropToUInt32(UString(), propVariant, bundle)) + if (bundle > 0 && bundle < numCPUs) + { + #ifndef Z7_ST + affinityMode.SetLevels(numCPUs, 2); + affinityMode.NumBundleThreads = bundle; + #endif + } + continue; + } + if (name.IsEqualTo("freq")) { UInt32 freq32 = 0; - RINOK(ParsePropToUInt32(L"", propVariant, freq32)); + RINOK(ParsePropToUInt32(UString(), propVariant, freq32)) if (freq32 == 0) return E_INVALIDARG; specifiedFreq = (UInt64)freq32 * 1000000; @@ -2547,46 +3827,48 @@ HRESULT Bench( if (name.IsPrefixedBy_Ascii_NoCase("mt")) { - UString s = name.Ptr(2); - if (s == L"*") + const UString s = name.Ptr(2); + if (s.IsEqualTo("*") + || (s.IsEmpty() + && propVariant.vt == VT_BSTR + && StringsAreEqual_Ascii(propVariant.bstrVal, "*"))) { multiThreadTests = true; continue; } - if (s.IsEmpty() && propVariant.vt == VT_BSTR) - { - if (wcscmp(propVariant.bstrVal, L"*") == 0) - { - multiThreadTests = true; - continue; - } - } - #ifndef _7ZIP_ST - RINOK(ParseMtProp(s, propVariant, numCPUs, numThreadsSpecified)); + #ifndef Z7_ST + RINOK(ParseMtProp(s, propVariant, numCPUs, numThreadsSpecified)) #endif continue; } - RINOK(method.ParseMethodFromPROPVARIANT(name, propVariant)); + RINOK(method.ParseMethodFromPROPVARIANT(name, propVariant)) } } if (printCallback) { AString s; - GetCpuName(s); + + #ifndef _WIN32 + s += "Compiler: "; + GetCompiler(s); + printCallback->Print(s); + printCallback->NewLine(); + s.Empty(); + #endif + + GetSystemInfoText(s); printCallback->Print(s); printCallback->NewLine(); } if (printCallback) { - printCallback->Print("CPU Freq:"); + printCallback->Print("1T CPU Freq (MHz):"); } - UInt64 complexInCommands = kComplexInCommands; - - if (printCallback /* || benchCallback */) + if (printCallback || freqCallback) { UInt64 numMilCommands = 1 << 6; if (specifiedFreq != 0) @@ -2598,17 +3880,23 @@ HRESULT Bench( for (int jj = 0;; jj++) { if (printCallback) - RINOK(printCallback->CheckBreak()); + RINOK(printCallback->CheckBreak()) UInt64 start = ::GetTimeCount(); UInt32 sum = (UInt32)start; sum = CountCpuFreq(sum, (UInt32)(numMilCommands * 1000000 / kNumFreqCommands), g_BenchCpuFreqTemp); + if (sum == 0xF1541213) + if (printCallback) + printCallback->Print(""); const UInt64 realDelta = ::GetTimeCount() - start; start = realDelta; if (start == 0) start = 1; - UInt64 freq = GetFreq(); + if (start > (UInt64)1 << 61) + start = 1; + const UInt64 freq = GetFreq(); // mips is constant in some compilers + const UInt64 hz = MyMultDiv64(numMilCommands * 1000000, freq, start); const UInt64 mipsVal = numMilCommands * freq / start; if (printCallback) { @@ -2619,172 +3907,570 @@ HRESULT Bench( else { // PrintNumber(*printCallback, start, 0); - PrintNumber(*printCallback, mipsVal, 5 + ((sum == 0xF1541213) ? 1 : 0)); + PrintNumber(*printCallback, mipsVal, 5); } } - /* - if (benchCallback) - benchCallback->AddCpuFreq(mipsVal); - */ + if (freqCallback) + { + RINOK(freqCallback->AddCpuFreq(1, hz, kBenchmarkUsageMult)) + } + + if (jj >= 1) + { + bool needStop = (numMilCommands >= (1 << + #ifdef _DEBUG + 7 + #else + 11 + #endif + )); + if (start >= freq * 16) + { + printCallback->Print(" (Cmplx)"); + if (!freqCallback) // we don't want complexity change for old gui lzma benchmark + { + needSetComplexity = true; + } + needStop = true; + } + if (needSetComplexity) + SetComplexCommandsMs(testTimeMs, false, mipsVal * 1000000, complexInCommands); + if (needStop) + break; + numMilCommands <<= 1; + } + } + if (freqCallback) + { + RINOK(freqCallback->FreqsFinished(1)) + } + } + + if (numThreadsSpecified >= 2) + if (printCallback || freqCallback) + { + if (printCallback) + printCallback->NewLine(); - if (jj >= 3) + /* it can show incorrect frequency for HT threads. + so we reduce freq test to (numCPUs / 2) */ + + UInt32 numThreads = numThreadsSpecified >= numCPUs / 2 ? numCPUs / 2: numThreadsSpecified; + if (numThreads < 1) + numThreads = 1; + + if (printCallback) + { + char s[128]; + ConvertUInt64ToString(numThreads, s); + printCallback->Print(s); + printCallback->Print("T CPU Freq (MHz):"); + } + UInt64 numMilCommands = 1 << + #ifdef _DEBUG + 7; + #else + 10; + #endif + + if (specifiedFreq != 0) + { + while (numMilCommands > 1 && specifiedFreq < (numMilCommands * 1000000)) + numMilCommands >>= 1; + } + + // for (int jj = 0;; jj++) + for (;;) + { + if (printCallback) + RINOK(printCallback->CheckBreak()) + + { + // PrintLeft(f, "CPU", kFieldSize_Name); + + // UInt32 resVal; + + CFreqBench fb; + fb.complexInCommands = numMilCommands * 1000000; + fb.numThreads = numThreads; + // showFreq; + // fb.showFreq = (freqTest == kNumCpuTests - 1 || specifiedFreq != 0); + fb.showFreq = true; + fb.specifiedFreq = 1; + + const HRESULT res = fb.FreqBench(NULL /* printCallback */ + #ifndef Z7_ST + , &affinityMode + #endif + ); + RINOK(res) + + if (freqCallback) + { + RINOK(freqCallback->AddCpuFreq(numThreads, fb.CpuFreqRes, fb.UsageRes)) + } + + if (printCallback) + { + /* + if (realDelta == 0) + { + printCallback->Print(" -"); + } + else + */ + { + // PrintNumber(*printCallback, start, 0); + PrintUsage(*printCallback, fb.UsageRes, 3); + printCallback->Print("%"); + PrintNumber(*printCallback, fb.CpuFreqRes / 1000000, 0); + printCallback->Print(" "); + + // PrintNumber(*printCallback, fb.UsageRes, 5); + } + } + } + // if (jj >= 1) { - SetComplexCommands(testTime, false, mipsVal * 1000000, complexInCommands); - if (jj >= 8 || start >= freq) + const bool needStop = (numMilCommands >= (1 << + #ifdef _DEBUG + 7 + #else + 11 + #endif + )); + if (needStop) break; - // break; // change it numMilCommands <<= 1; } } + if (freqCallback) + { + RINOK(freqCallback->FreqsFinished(numThreads)) + } } + if (printCallback) { printCallback->NewLine(); printCallback->NewLine(); PrintRequirements(*printCallback, "size: ", ramSize_Defined, ramSize, "CPU hardware threads:", numCPUs); + printCallback->Print(GetProcessThreadsInfo(threadsInfo)); + printCallback->NewLine(); } if (numThreadsSpecified < 1 || numThreadsSpecified > kNumThreadsMax) return E_INVALIDARG; - UInt32 dict; - bool dictIsDefined = method.Get_DicSize(dict); + UInt64 dict = (UInt64)1 << startDicLog; + const bool dictIsDefined = (isFixedDict || method.Get_DicSize(dict)); + + const unsigned level = method.GetLevel(); - if (method.MethodName.IsEmpty()) - method.MethodName = "LZMA"; + AString &methodName = method.MethodName; + const AString original_MethodName = methodName; + if (methodName.IsEmpty()) + methodName = "LZMA"; if (benchCallback) { CBenchProps benchProps; benchProps.SetLzmaCompexity(); - UInt32 dictSize = method.Get_Lzma_DicSize(); - UInt32 uncompressedDataSize = kAdditionalSize + dictSize; + const UInt64 dictSize = method.Get_Lzma_DicSize(); + + size_t uncompressedDataSize; + if (use_fileData) + { + uncompressedDataSize = fileDataBuffer.Size(); + } + else + { + uncompressedDataSize = kAdditionalSize + (size_t)dictSize; + if (uncompressedDataSize < dictSize) + return E_INVALIDARG; + } + return MethodBench( EXTERNAL_CODECS_LOC_VARS complexInCommands, + #ifndef Z7_ST true, numThreadsSpecified, + &affinityMode, + #endif method, - uncompressedDataSize, fileDataBuffer.Buffer, + uncompressedDataSize, (const Byte *)fileDataBuffer, kOldLzmaDictBits, printCallback, benchCallback, &benchProps); } - AString methodName = method.MethodName; if (methodName.IsEqualTo_Ascii_NoCase("CRC")) methodName = "crc32"; - method.MethodName = methodName; + CMethodId hashID; - - if (FindHashMethod(EXTERNAL_CODECS_LOC_VARS methodName, hashID)) + const bool isHashMethod = FindHashMethod(EXTERNAL_CODECS_LOC_VARS methodName, hashID); + int codecIndex = -1; + bool isFilter = false; + if (!isHashMethod) + { + UInt32 numStreams; + codecIndex = FindMethod_Index(EXTERNAL_CODECS_LOC_VARS original_MethodName, + true, // encode + hashID, numStreams, isFilter); + // we can allow non filter for BW tests + if (!isFilter) codecIndex = -1; + } + + CBenchCallbackToPrint callback; + callback.Init(); + callback._file = printCallback; + + if (isHashMethod || codecIndex != -1) { if (!printCallback) return S_FALSE; IBenchPrintCallback &f = *printCallback; + + UInt64 dict64 = dict; if (!dictIsDefined) - dict = (1 << 24); + dict64 = (1 << 27); + if (use_fileData) + { + if (!dictIsDefined) + dict64 = fileDataBuffer.Size(); + else if (dict64 > fileDataBuffer.Size()) + dict64 = fileDataBuffer.Size(); + } + for (;;) + { + const int index = method.FindProp(NCoderPropID::kDictionarySize); + if (index < 0) + break; + method.Props.Delete((unsigned)index); + } - // methhodName.RemoveChar(L'-'); - UInt32 complexity = 10000; + // methodName.RemoveChar(L'-'); + Int32 complexity = 16 * k_Hash_Complex_Mult; // for unknown hash method const UInt32 *checkSum = NULL; + int benchIndex = -1; + + if (isHashMethod) { - for (unsigned i = 0; i < ARRAY_SIZE(g_Hash); i++) + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_Hash); i++) { const CBenchHash &h = g_Hash[i]; - AString s = h.Name; - AString hProp; - int propPos = s.Find(':'); + AString benchMethod (h.Name); + AString benchProps; + const int propPos = benchMethod.Find(':'); if (propPos >= 0) { - hProp = s.Ptr(propPos + 1); - s.DeleteFrom(propPos); + benchProps = benchMethod.Ptr((unsigned)(propPos + 1)); + benchMethod.DeleteFrom((unsigned)propPos); } - if (AreSameMethodNames(s, methodName)) + if (AreSameMethodNames(benchMethod, methodName)) { - complexity = h.Complex; - checkSum = &h.CheckSum; - if (method.PropsString.IsEqualTo_Ascii_NoCase(hProp)) - break; + const bool sameProps = method.PropsString.IsEqualTo_Ascii_NoCase(benchProps); + /* + bool isMainMethod = method.PropsString.IsEmpty(); + if (isMainMethod) + isMainMethod = !checkSum + || (benchMethod.IsEqualTo_Ascii_NoCase("crc32") && benchProps.IsEqualTo_Ascii_NoCase("8")); + if (sameProps || isMainMethod) + */ + { + complexity = (Int32)h.Complex; + checkSum = &h.CheckSum; + if (sameProps) + break; + /* + if property. is not specified, we use the complexity + for latest fastest method (crc32:64) + */ + } + } + } + // if (!checkSum) return E_NOTIMPL; + } + else + { + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_Bench); i++) + { + const CBenchMethod &bench = g_Bench[i]; + AString benchMethod (bench.Name); + AString benchProps; + const int propPos = benchMethod.Find(':'); + if (propPos >= 0) + { + benchProps = benchMethod.Ptr((unsigned)(propPos + 1)); + benchMethod.DeleteFrom((unsigned)propPos); + } + + if (AreSameMethodNames(benchMethod, methodName)) + { + const bool sameProps = method.PropsString.IsEqualTo_Ascii_NoCase(benchProps); + // bool isMainMethod = method.PropsString.IsEmpty(); + // if (sameProps || isMainMethod) + { + benchIndex = (int)i; + if (sameProps) + break; + } } } + // if (benchIndex < 0) return E_NOTIMPL; } - f.NewLine(); - f.Print("Size"); - const unsigned kFieldSize_CrcSpeed = 6; - unsigned numThreadsTests = 0; - for (;;) { - UInt32 t = GetNumThreadsNext(numThreadsTests, numThreadsSpecified); - PrintNumber(f, t, kFieldSize_CrcSpeed); - numThreadsTests++; - if (t >= numThreadsSpecified) - break; + /* we count usage only for crc and filter. non-filters are not supported */ + UInt64 usage = (1 << 20); + UInt64 bufSize = dict64; + UInt32 numBlocks = isHashMethod ? 1 : 3; + if (use_fileData) + { + usage += fileDataBuffer.Size(); + if (bufSize > fileDataBuffer.Size()) + bufSize = fileDataBuffer.Size(); + if (isHashMethod) + { + numBlocks = 0; + #ifndef Z7_ST + if (numThreadsSpecified != 1) + numBlocks = (k_Crc_CreateLocalBuf_For_File ? 1 : 0); + #endif + } + } + usage += numThreadsSpecified * bufSize * numBlocks; + Print_Usage_and_Threads(f, usage, numThreadsSpecified); } + + CUIntVector numThreadsVector; + { + unsigned nt = numThreads_Start; + for (;;) + { + if (nt > numThreadsSpecified) + break; + numThreadsVector.Add(nt); + const unsigned next = nt * 2; + const UInt32 ntHalf= numThreadsSpecified / 2; + if (ntHalf > nt && ntHalf < next) + numThreadsVector.Add(ntHalf); + if (numThreadsSpecified > nt && numThreadsSpecified < next) + numThreadsVector.Add(numThreadsSpecified); + nt = next; + } + } + + unsigned numColumns = isHashMethod ? 1 : 2; + CTempValues speedTotals; + CTempValues usageTotals; + { + const unsigned numItems = numThreadsVector.Size() * numColumns; + speedTotals.Alloc(numItems); + usageTotals.Alloc(numItems); + for (unsigned i = 0; i < numItems; i++) + { + speedTotals.Values[i] = 0; + usageTotals.Values[i] = 0; + } + } + f.NewLine(); - f.NewLine(); - CTempValues speedTotals(numThreadsTests); + for (unsigned line = 0; line < 3; line++) { - for (unsigned ti = 0; ti < numThreadsTests; ti++) - speedTotals.Values[ti] = 0; + f.NewLine(); + f.Print(line == 0 ? "THRD" : line == 1 ? " " : "Size"); + FOR_VECTOR (ti, numThreadsVector) + { + if (ti != 0) + Print_Delimiter(f); + if (line == 0) + { + PrintSpaces(f, (kFieldSize_CrcSpeed + kFieldSize_Usage + 2) * (numColumns - 1)); + PrintNumber(f, numThreadsVector[ti], 1 + kFieldSize_Usage + kFieldSize_CrcSpeed); + } + else + { + for (unsigned c = 0; c < numColumns; c++) + { + PrintRight(f, line == 1 ? "Usage" : "%", kFieldSize_Usage + 1); + PrintRight(f, line == 1 ? "BW" : "MB/s", kFieldSize_CrcSpeed + 1); + } + } + } } - + f.NewLine(); + UInt64 numSteps = 0; - for (UInt32 i = 0; i < numIterations; i++) + + // for (UInt32 iter = 0; iter < numIterations; iter++) + // { + unsigned pow = 10; // kNumHashDictBits + if (startDicLog_Defined) + pow = startDicLog; + + // #define NUM_SUB_BITS 2 + // pow <<= NUM_SUB_BITS; + for (;; pow++) { - for (unsigned pow = 10; pow < 32; pow++) + const UInt64 bufSize = (UInt64)1 << pow; + // UInt64 bufSize = (UInt64)1 << (pow >> NUM_SUB_BITS); + // bufSize += ((UInt64)pow & ((1 << NUM_SUB_BITS) - 1)) << ((pow >> NUM_SUB_BITS) - NUM_SUB_BITS); + + size_t dataSize = fileDataBuffer.Size(); + if (dataSize > bufSize || !use_fileData) + dataSize = (size_t)bufSize; + + for (UInt32 iter = 0; iter < numIterations; iter++) { - UInt32 bufSize = (UInt32)1 << pow; - if (bufSize > dict) - break; - char s[16]; - ConvertUInt32ToString(pow, s); - unsigned pos = MyStringLen(s); - s[pos++] = ':'; - s[pos++] = ' '; - s[pos] = 0; - f.Print(s); - - for (unsigned ti = 0; ti < numThreadsTests; ti++) + Print_Pow(f, pow); + // PrintNumber(f, bufSize >> 10, 4); + + FOR_VECTOR (ti, numThreadsVector) { - RINOK(f.CheckBreak()); - UInt32 t = GetNumThreadsNext(ti, numThreadsSpecified); - UInt64 speed = 0; - RINOK(CrcBench(EXTERNAL_CODECS_LOC_VARS complexInCommands, - t, bufSize, speed, - complexity, + RINOK(f.CheckBreak()) + const UInt32 numThreads = numThreadsVector[ti]; + if (isHashMethod) + { + UInt64 speed = 0; + UInt64 usage = 0; + const HRESULT res = CrcBench(EXTERNAL_CODECS_LOC_VARS complexInCommands, + numThreads, + dataSize, (const Byte *)fileDataBuffer, + speed, usage, + (UInt32)complexity, 1, // benchWeight, - (pow == kNumHashDictBits) ? checkSum : NULL, method, NULL, NULL, false, 0)); - PrintNumber(f, (speed >> 20), kFieldSize_CrcSpeed); - speedTotals.Values[ti] += speed; + (pow == kNumHashDictBits && !use_fileData) ? checkSum : NULL, + method, + &f, + #ifndef Z7_ST + &affinityMode, + #endif + false, // showRating + NULL, false, 0); + RINOK(res) + + if (ti != 0) + Print_Delimiter(f); + + Bench_BW_Print_Usage_Speed(f, usage, speed); + speedTotals.Values[ti] += speed; + usageTotals.Values[ti] += usage; + } + else + { + { + unsigned keySize = 32; + if (IsString1PrefixedByString2(methodName, "AES128")) keySize = 16; + else if (IsString1PrefixedByString2(methodName, "AES192")) keySize = 24; + callback.BenchProps.KeySize = keySize; + } + + COneMethodInfo method2 = method; + unsigned bench_DictBits; + + if (benchIndex >= 0) + { + const CBenchMethod &bench = g_Bench[benchIndex]; + callback.BenchProps.EncComplex = bench.EncComplex; + callback.BenchProps.DecComplexUnc = bench.DecComplexUnc; + callback.BenchProps.DecComplexCompr = bench.DecComplexCompr; + bench_DictBits = bench.DictBits; + // bench_DictBits = kOldLzmaDictBits; = 32 default : for debug + } + else + { + bench_DictBits = kOldLzmaDictBits; // = 32 default + if (isFilter) + { + const unsigned k_UnknownCoderComplexity = 4; + callback.BenchProps.EncComplex = k_UnknownCoderComplexity; + callback.BenchProps.DecComplexUnc = k_UnknownCoderComplexity; + } + else + { + callback.BenchProps.EncComplex = 1 << 10; + callback.BenchProps.DecComplexUnc = 1 << 6; + } + callback.BenchProps.DecComplexCompr = 0; + } + callback.NeedPrint = false; + + if (StringsAreEqualNoCase_Ascii(method2.MethodName, "LZMA")) + { + const NCOM::CPropVariant propVariant = (UInt32)pow; + RINOK(method2.ParseMethodFromPROPVARIANT((UString)"d", propVariant)) + } + + const HRESULT res = MethodBench( + EXTERNAL_CODECS_LOC_VARS + complexInCommands, + #ifndef Z7_ST + false, // oldLzmaBenchMode + numThreadsVector[ti], + &affinityMode, + #endif + method2, + dataSize, (const Byte *)fileDataBuffer, + bench_DictBits, + printCallback, + &callback, + &callback.BenchProps); + RINOK(res) + + if (ti != 0) + Print_Delimiter(f); + + for (unsigned i = 0; i < 2; i++) + { + const CBenchInfo &bi = callback.BenchInfo_Results[i]; + const UInt64 usage = bi.GetUsage(); + const UInt64 speed = bi.GetUnpackSizeSpeed(); + usageTotals.Values[ti * 2 + i] += usage; + speedTotals.Values[ti * 2 + i] += speed; + Bench_BW_Print_Usage_Speed(f, usage, speed); + } + } } + f.NewLine(); numSteps++; } + if (dataSize >= dict64) + break; } + if (numSteps != 0) { - f.NewLine(); f.Print("Avg:"); - for (unsigned ti = 0; ti < numThreadsTests; ti++) + for (unsigned ti = 0; ti < numThreadsVector.Size(); ti++) { - PrintNumber(f, ((speedTotals.Values[ti] / numSteps) >> 20), kFieldSize_CrcSpeed); + if (ti != 0) + Print_Delimiter(f); + for (unsigned i = 0; i < numColumns; i++) + Bench_BW_Print_Usage_Speed(f, + usageTotals.Values[ti * numColumns + i] / numSteps, + speedTotals.Values[ti * numColumns + i] / numSteps); } f.NewLine(); } + return S_OK; } bool use2Columns = false; - bool totalBenchMode = (method.MethodName.IsEqualTo_Ascii_NoCase("*")); + bool totalBenchMode = false; bool onlyHashBench = false; - if (method.MethodName.IsEqualTo_Ascii_NoCase("hash")) + if (methodName.IsEqualTo_Ascii_NoCase("hash")) { onlyHashBench = true; + methodName = "*"; totalBenchMode = true; } + else if (methodName.Find('*') >= 0) + totalBenchMode = true; // ---------- Threads loop ---------- for (unsigned threadsPassIndex = 0; threadsPassIndex < 3; threadsPassIndex++) @@ -2815,10 +4501,6 @@ HRESULT Bench( } } - CBenchCallbackToPrint callback; - callback.Init(); - callback._file = printCallback; - IBenchPrintCallback &f = *printCallback; if (threadsPassIndex > 0) @@ -2827,7 +4509,7 @@ HRESULT Bench( f.NewLine(); } - if (!dictIsDefined) + if (!dictIsDefined && !onlyHashBench) { const unsigned dicSizeLog_Main = (totalBenchMode ? 24 : 25); unsigned dicSizeLog = dicSizeLog_Main; @@ -2838,10 +4520,10 @@ HRESULT Bench( if (ramSize_Defined) for (; dicSizeLog > kBenchMinDicLogSize; dicSizeLog--) - if (GetBenchMemoryUsage(numThreads, ((UInt32)1 << dicSizeLog), totalBenchMode) + (8 << 20) <= ramSize) + if (GetBenchMemoryUsage(numThreads, (int)level, ((UInt64)1 << dicSizeLog), totalBenchMode) + (8 << 20) <= ramSize) break; - dict = (UInt32)1 << dicSizeLog; + dict = (UInt64)1 << dicSizeLog; if (totalBenchMode && dicSizeLog != dicSizeLog_Main) { @@ -2851,7 +4533,13 @@ HRESULT Bench( } } - PrintRequirements(f, "usage:", true, GetBenchMemoryUsage(numThreads, dict, totalBenchMode), "Benchmark threads: ", numThreads); + Print_Usage_and_Threads(f, + onlyHashBench ? + GetBenchMemoryUsage_Hash(numThreads, dict) : + GetBenchMemoryUsage(numThreads, (int)level, dict, totalBenchMode), + numThreads); + + f.NewLine(); f.NewLine(); @@ -2934,6 +4622,7 @@ HRESULT Bench( if (specifiedFreq != 0) cpuFreq = specifiedFreq; + // bool showTotalSpeed = false; if (totalBenchMode) { @@ -2941,96 +4630,171 @@ HRESULT Bench( { if (i != 0) printCallback->NewLine(); - HRESULT res; const unsigned kNumCpuTests = 3; for (unsigned freqTest = 0; freqTest < kNumCpuTests; freqTest++) { PrintLeft(f, "CPU", kFieldSize_Name); - UInt32 resVal; - RINOK(FreqBench(complexInCommands, numThreads, printCallback, - (freqTest == kNumCpuTests - 1 || specifiedFreq != 0), // showFreq - specifiedFreq, - cpuFreq, resVal)); + + // UInt32 resVal; + + CFreqBench fb; + fb.complexInCommands = complexInCommands; + fb.numThreads = numThreads; + // showFreq; + fb.showFreq = (freqTest == kNumCpuTests - 1 || specifiedFreq != 0); + fb.specifiedFreq = specifiedFreq; + + const HRESULT res = fb.FreqBench(printCallback + #ifndef Z7_ST + , &affinityMode + #endif + ); + RINOK(res) + + cpuFreq = fb.CpuFreqRes; callback.NewLine(); if (specifiedFreq != 0) cpuFreq = specifiedFreq; + if (testTimeMs >= 1000) if (freqTest == kNumCpuTests - 1) - SetComplexCommands(testTime, specifiedFreq != 0, cpuFreq, complexInCommands); + { + // SetComplexCommandsMs(testTimeMs, specifiedFreq != 0, cpuFreq, complexInCommands); + } } callback.NewLine(); + // return S_OK; // change it + callback.SetFreq(true, cpuFreq); if (!onlyHashBench) { - res = TotalBench(EXTERNAL_CODECS_LOC_VARS - complexInCommands, numThreads, - dictIsDefined || fileDataBuffer.Buffer, // forceUnpackSize - fileDataBuffer.Buffer ? fileDataBuffer.BufferSize : dict, - fileDataBuffer.Buffer, + size_t dataSize = (size_t)dict; + if (use_fileData) + { + dataSize = fileDataBuffer.Size(); + if (dictIsDefined && dataSize > dict) + dataSize = (size_t)dict; + } + + const HRESULT res = TotalBench(EXTERNAL_CODECS_LOC_VARS + method, complexInCommands, + #ifndef Z7_ST + numThreads, + &affinityMode, + #endif + dictIsDefined || use_fileData, // forceUnpackSize + dataSize, + (const Byte *)fileDataBuffer, printCallback, &callback); - RINOK(res); + RINOK(res) } - res = TotalBench_Hash(EXTERNAL_CODECS_LOC_VARS complexInCommands, numThreads, - 1 << kNumHashDictBits, printCallback, &callback, &callback.EncodeRes, true, cpuFreq); - RINOK(res); + { + size_t dataSize = (size_t)1 << kNumHashDictBits; + if (dictIsDefined) + { + dataSize = (size_t)dict; + if (dataSize != dict) + return E_OUTOFMEMORY; + } + if (use_fileData) + { + dataSize = fileDataBuffer.Size(); + if (dictIsDefined && dataSize > dict) + dataSize = (size_t)dict; + } + + const HRESULT res = TotalBench_Hash(EXTERNAL_CODECS_LOC_VARS + method, complexInCommands, + numThreads, + dataSize, (const Byte *)fileDataBuffer, + printCallback, &callback, + #ifndef Z7_ST + &affinityMode, + #endif + &callback.EncodeRes, true, cpuFreq); + RINOK(res) + } callback.NewLine(); { PrintLeft(f, "CPU", kFieldSize_Name); - UInt32 resVal; - UInt64 cpuFreqLastTemp = cpuFreq; - RINOK(FreqBench(complexInCommands, numThreads, printCallback, - specifiedFreq != 0, // showFreq - specifiedFreq, - cpuFreqLastTemp, resVal)); + + CFreqBench fb; + fb.complexInCommands = complexInCommands; + fb.numThreads = numThreads; + // showFreq; + fb.showFreq = (specifiedFreq != 0); + fb.specifiedFreq = specifiedFreq; + + const HRESULT res = fb.FreqBench(printCallback + #ifndef Z7_ST + , &affinityMode + #endif + ); + RINOK(res) callback.NewLine(); } } } else { - bool needSetComplexity = true; + needSetComplexity = true; if (!methodName.IsEqualTo_Ascii_NoCase("LZMA")) { - for (unsigned i = 0; i < ARRAY_SIZE(g_Bench); i++) + unsigned i; + for (i = 0; i < Z7_ARRAY_SIZE(g_Bench); i++) { const CBenchMethod &h = g_Bench[i]; - AString s = h.Name; - if (AreSameMethodNames(h.Name, methodName)) + AString benchMethod (h.Name); + AString benchProps; + const int propPos = benchMethod.Find(':'); + if (propPos >= 0) { - callback.BenchProps.EncComplex = h.EncComplex; - callback.BenchProps.DecComplexCompr = h.DecComplexCompr; - callback.BenchProps.DecComplexUnc = h.DecComplexUnc;; - needSetComplexity = false; - break; + benchProps = benchMethod.Ptr((unsigned)(propPos + 1)); + benchMethod.DeleteFrom((unsigned)propPos); + } + + if (AreSameMethodNames(benchMethod, methodName)) + { + if (benchProps.IsEmpty() + || (benchProps == "x5" && method.PropsString.IsEmpty()) + || method.PropsString.IsPrefixedBy_Ascii_NoCase(benchProps)) + { + callback.BenchProps.EncComplex = h.EncComplex; + callback.BenchProps.DecComplexCompr = h.DecComplexCompr; + callback.BenchProps.DecComplexUnc = h.DecComplexUnc; + needSetComplexity = false; + break; + } } } + /* + if (i == Z7_ARRAY_SIZE(g_Bench)) + return E_NOTIMPL; + */ } if (needSetComplexity) callback.BenchProps.SetLzmaCompexity(); + if (startDicLog < kBenchMinDicLogSize) + startDicLog = kBenchMinDicLogSize; + for (unsigned i = 0; i < numIterations; i++) { - const unsigned kStartDicLog = 22; - unsigned pow = (dict < ((UInt32)1 << kStartDicLog)) ? kBenchMinDicLogSize : kStartDicLog; + unsigned pow = (dict < GetDictSizeFromLog(startDicLog)) ? kBenchMinDicLogSize : (unsigned)startDicLog; if (!multiDict) - pow = 31; - while (((UInt32)1 << pow) > dict && pow > 0) + pow = 32; + while (GetDictSizeFromLog(pow) > dict && pow > 0) pow--; - for (; ((UInt32)1 << pow) <= dict; pow++) + for (; GetDictSizeFromLog(pow) <= dict; pow++) { - char s[16]; - ConvertUInt32ToString(pow, s); - unsigned pos = MyStringLen(s); - s[pos++] = ':'; - s[pos] = 0; - PrintLeft(f, s, kFieldSize_SmallName); - callback.DictSize = (UInt32)1 << pow; + Print_Pow(f, pow); + callback.DictSize = (UInt64)1 << pow; COneMethodInfo method2 = method; @@ -3040,30 +4804,35 @@ HRESULT Bench( // method2 can have two different dictionary size properties. // And last property is main. NCOM::CPropVariant propVariant = (UInt32)pow; - RINOK(method2.ParseMethodFromPROPVARIANT(L"d", propVariant)); + RINOK(method2.ParseMethodFromPROPVARIANT((UString)"d", propVariant)) } size_t uncompressedDataSize; - if (fileDataBuffer.Buffer) + if (use_fileData) { - uncompressedDataSize = fileDataBuffer.BufferSize; + uncompressedDataSize = fileDataBuffer.Size(); } else { - uncompressedDataSize = callback.DictSize; + uncompressedDataSize = (size_t)callback.DictSize; + if (uncompressedDataSize != callback.DictSize) + return E_OUTOFMEMORY; if (uncompressedDataSize >= (1 << 18)) uncompressedDataSize += kAdditionalSize; } - HRESULT res = MethodBench( + const HRESULT res = MethodBench( EXTERNAL_CODECS_LOC_VARS complexInCommands, + #ifndef Z7_ST true, numThreads, + &affinityMode, + #endif method2, - uncompressedDataSize, fileDataBuffer.Buffer, + uncompressedDataSize, (const Byte *)fileDataBuffer, kOldLzmaDictBits, printCallback, &callback, &callback.BenchProps); f.NewLine(); - RINOK(res); + RINOK(res) if (!multiDict) break; } @@ -3083,16 +4852,19 @@ HRESULT Bench( if (use2Columns) { PrintLeft(f, "Avr:", callback.NameFieldSize); - PrintTotals(f, showFreq, cpuFreq, callback.EncodeRes); + PrintTotals(f, showFreq, cpuFreq, !totalBenchMode, callback.EncodeRes); f.Print(kSep); - PrintTotals(f, showFreq, cpuFreq, callback.DecodeRes); + PrintTotals(f, showFreq, cpuFreq, !totalBenchMode, callback.DecodeRes); f.NewLine(); } PrintLeft(f, "Tot:", callback.NameFieldSize); CTotalBenchRes midRes; - midRes.SetSum(callback.EncodeRes, callback.DecodeRes); - PrintTotals(f, showFreq, cpuFreq, midRes); + midRes = callback.EncodeRes; + midRes.Update_With_Res(callback.DecodeRes); + + // midRes.SetSum(callback.EncodeRes, callback.DecodeRes); + PrintTotals(f, showFreq, cpuFreq, false, midRes); f.NewLine(); } diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/Bench.h b/3rdparty/lzma/CPP/7zip/UI/Common/Bench.h index 841250ef2cc..313676dd5a1 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/Bench.h +++ b/3rdparty/lzma/CPP/7zip/UI/Common/Bench.h @@ -1,11 +1,15 @@ // Bench.h -#ifndef __7ZIP_BENCH_H -#define __7ZIP_BENCH_H +#ifndef ZIP7_INC_7ZIP_BENCH_H +#define ZIP7_INC_7ZIP_BENCH_H + +#include "../../../Windows/System.h" #include "../../Common/CreateCoder.h" #include "../../UI/Common/Property.h" +UInt64 Benchmark_GetUsage_Percents(UInt64 usage); + struct CBenchInfo { UInt64 GlobalTime; @@ -15,41 +19,103 @@ struct CBenchInfo UInt64 UnpackSize; UInt64 PackSize; UInt64 NumIterations; + + /* + during Code(): we track benchInfo only from one thread (theads with index[0]) + NumIterations means number of threads + UnpackSize and PackSize are total sizes of all iterations of current thread + after Code(): + NumIterations means the number of Iterations + UnpackSize and PackSize are total sizes of all threads + */ CBenchInfo(): NumIterations(0) {} + UInt64 GetUsage() const; UInt64 GetRatingPerUsage(UInt64 rating) const; - UInt64 GetSpeed(UInt64 numCommands) const; + UInt64 GetSpeed(UInt64 numUnits) const; + UInt64 GetUnpackSizeSpeed() const { return GetSpeed(UnpackSize * NumIterations); } + + UInt64 Get_UnpackSize_Full() const { return UnpackSize * NumIterations; } + + UInt64 GetRating_LzmaEnc(UInt64 dictSize) const; + UInt64 GetRating_LzmaDec() const; }; -struct IBenchCallback + +struct CTotalBenchRes { - virtual HRESULT SetFreq(bool showFreq, UInt64 cpuFreq) = 0; - virtual HRESULT SetEncodeResult(const CBenchInfo &info, bool final) = 0; - virtual HRESULT SetDecodeResult(const CBenchInfo &info, bool final) = 0; + // UInt64 NumIterations1; // for Usage + UInt64 NumIterations2; // for Rating / RPU + + UInt64 Rating; + UInt64 Usage; + UInt64 RPU; + UInt64 Speed; + + void Init() { /* NumIterations1 = 0; */ NumIterations2 = 0; Rating = 0; Usage = 0; RPU = 0; Speed = 0; } + + void SetSum(const CTotalBenchRes &r1, const CTotalBenchRes &r2) + { + Rating = (r1.Rating + r2.Rating); + Usage = (r1.Usage + r2.Usage); + RPU = (r1.RPU + r2.RPU); + Speed = (r1.Speed + r2.Speed); + // NumIterations1 = (r1.NumIterations1 + r2.NumIterations1); + NumIterations2 = (r1.NumIterations2 + r2.NumIterations2); + } + + void Generate_From_BenchInfo(const CBenchInfo &info); + void Mult_For_Weight(unsigned weight); + void Update_With_Res(const CTotalBenchRes &r); }; -UInt64 GetCompressRating(UInt32 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size); -UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations); const unsigned kBenchMinDicLogSize = 18; -UInt64 GetBenchMemoryUsage(UInt32 numThreads, UInt32 dictionary, bool totalBench = false); +UInt64 GetBenchMemoryUsage(UInt32 numThreads, int level, UInt64 dictionary, bool totalBench); -struct IBenchPrintCallback +Z7_PURE_INTERFACES_BEGIN +DECLARE_INTERFACE(IBenchCallback) +{ + // virtual HRESULT SetFreq(bool showFreq, UInt64 cpuFreq) = 0; + virtual HRESULT SetEncodeResult(const CBenchInfo &info, bool final) = 0; + virtual HRESULT SetDecodeResult(const CBenchInfo &info, bool final) = 0; +}; + +DECLARE_INTERFACE(IBenchPrintCallback) { virtual void Print(const char *s) = 0; virtual void NewLine() = 0; virtual HRESULT CheckBreak() = 0; }; +DECLARE_INTERFACE(IBenchFreqCallback) +{ + virtual HRESULT AddCpuFreq(unsigned numThreads, UInt64 freq, UInt64 usage) = 0; + virtual HRESULT FreqsFinished(unsigned numThreads) = 0; +}; +Z7_PURE_INTERFACES_END + HRESULT Bench( DECL_EXTERNAL_CODECS_LOC_VARS IBenchPrintCallback *printCallback, IBenchCallback *benchCallback, const CObjectVector<CProperty> &props, UInt32 numIterations, - bool multiDict - ); + bool multiDict, + IBenchFreqCallback *freqCallback = NULL); + +AString GetProcessThreadsInfo(const NWindows::NSystem::CProcessAffinity &ti); + +void GetSysInfo(AString &s1, AString &s2); +void GetCpuName(AString &s); +void AddCpuFeatures(AString &s); + +#ifdef Z7_LARGE_PAGES +void Add_LargePages_String(AString &s); +#else +// #define Add_LargePages_String +#endif #endif diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/DefaultName.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/DefaultName.cpp index 02f611c3d18..8c34ffc7348 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/DefaultName.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Common/DefaultName.cpp @@ -20,7 +20,7 @@ static UString GetDefaultName3(const UString &fileName, int dotPos = fileName.ReverseFind_Dot(); if (dotPos > 0) - return fileName.Left(dotPos) + addSubExtension; + return fileName.Left((unsigned)dotPos) + addSubExtension; if (addSubExtension.IsEmpty()) return fileName + L'~'; diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/DefaultName.h b/3rdparty/lzma/CPP/7zip/UI/Common/DefaultName.h index df164560275..46f6e9e67e2 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/DefaultName.h +++ b/3rdparty/lzma/CPP/7zip/UI/Common/DefaultName.h @@ -1,7 +1,7 @@ // DefaultName.h -#ifndef __DEFAULT_NAME_H -#define __DEFAULT_NAME_H +#ifndef ZIP7_INC_DEFAULT_NAME_H +#define ZIP7_INC_DEFAULT_NAME_H #include "../../../Common/MyString.h" diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/DirItem.h b/3rdparty/lzma/CPP/7zip/UI/Common/DirItem.h index 4286b4e8db0..ae8493766fa 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/DirItem.h +++ b/3rdparty/lzma/CPP/7zip/UI/Common/DirItem.h @@ -1,11 +1,17 @@ // DirItem.h -#ifndef __DIR_ITEM_H -#define __DIR_ITEM_H +#ifndef ZIP7_INC_DIR_ITEM_H +#define ZIP7_INC_DIR_ITEM_H + +#ifdef _WIN32 +#include "../../../Common/MyLinux.h" +#endif #include "../../../Common/MyString.h" #include "../../../Windows/FileFind.h" +#include "../../../Windows/PropVariant.h" +#include "../../../Windows/TimeUtils.h" #include "../../Common/UniqBlocks.h" @@ -20,9 +26,18 @@ struct CDirItemsStat UInt64 AltStreamsSize; UInt64 NumErrors; - // UInt64 GetTotalItems() const { return NumDirs + NumFiles + NumAltStreams; } + // UInt64 Get_NumItems() const { return NumDirs + NumFiles + NumAltStreams; } + UInt64 Get_NumDataItems() const { return NumFiles + NumAltStreams; } UInt64 GetTotalBytes() const { return FilesSize + AltStreamsSize; } + + bool IsEmpty() const { return + 0 == NumDirs + && 0 == NumFiles + && 0 == NumAltStreams + && 0 == FilesSize + && 0 == AltStreamsSize + && 0 == NumErrors; } CDirItemsStat(): NumDirs(0), @@ -34,42 +49,250 @@ struct CDirItemsStat {} }; -#define INTERFACE_IDirItemsCallback(x) \ - virtual HRESULT ScanError(const FString &path, DWORD systemError) x; \ - virtual HRESULT ScanProgress(const CDirItemsStat &st, const FString &path, bool isDir) x; \ -struct IDirItemsCallback +struct CDirItemsStat2: public CDirItemsStat { - INTERFACE_IDirItemsCallback(=0) + UInt64 Anti_NumDirs; + UInt64 Anti_NumFiles; + UInt64 Anti_NumAltStreams; + + // UInt64 Get_NumItems() const { return Anti_NumDirs + Anti_NumFiles + Anti_NumAltStreams + CDirItemsStat::Get_NumItems(); } + UInt64 Get_NumDataItems2() const { return Anti_NumFiles + Anti_NumAltStreams + CDirItemsStat::Get_NumDataItems(); } + + bool IsEmpty() const { return CDirItemsStat::IsEmpty() + && 0 == Anti_NumDirs + && 0 == Anti_NumFiles + && 0 == Anti_NumAltStreams; } + + CDirItemsStat2(): + Anti_NumDirs(0), + Anti_NumFiles(0), + Anti_NumAltStreams(0) + {} }; -struct CDirItem + +Z7_PURE_INTERFACES_BEGIN + +#define Z7_IFACEN_IDirItemsCallback(x) \ + virtual HRESULT ScanError(const FString &path, DWORD systemError) x \ + virtual HRESULT ScanProgress(const CDirItemsStat &st, const FString &path, bool isDir) x \ + +Z7_IFACE_DECL_PURE(IDirItemsCallback) + +Z7_PURE_INTERFACES_END + + +struct CArcTime +{ + FILETIME FT; + UInt16 Prec; + Byte Ns100; + bool Def; + + CArcTime() + { + Clear(); + } + + void Clear() + { + FT.dwHighDateTime = FT.dwLowDateTime = 0; + Prec = 0; + Ns100 = 0; + Def = false; + } + + bool IsZero() const + { + return FT.dwLowDateTime == 0 && FT.dwHighDateTime == 0 && Ns100 == 0; + } + + int CompareWith(const CArcTime &a) const + { + const int res = CompareFileTime(&FT, &a.FT); + if (res != 0) + return res; + if (Ns100 < a.Ns100) return -1; + if (Ns100 > a.Ns100) return 1; + return 0; + } + + UInt64 Get_FILETIME_as_UInt64() const + { + return (((UInt64)FT.dwHighDateTime) << 32) + FT.dwLowDateTime; + } + + UInt32 Get_DosTime() const + { + FILETIME ft2 = FT; + if ((Prec == k_PropVar_TimePrec_Base + 8 || + Prec == k_PropVar_TimePrec_Base + 9) + && Ns100 != 0) + { + UInt64 u64 = Get_FILETIME_as_UInt64(); + // we round up even small (ns < 100ns) as FileTimeToDosTime() + if (u64 % 20000000 == 0) + { + u64++; + ft2.dwHighDateTime = (DWORD)(u64 >> 32); + ft2.dwHighDateTime = (DWORD)u64; + } + } + // FileTimeToDosTime() is expected to round up in Windows + UInt32 dosTime; + // we use simplified code with utctime->dos. + // do we need local time instead here? + NWindows::NTime::FileTime_To_DosTime(ft2, dosTime); + return dosTime; + } + + int GetNumDigits() const + { + if (Prec == k_PropVar_TimePrec_Unix || + Prec == k_PropVar_TimePrec_DOS) + return 0; + if (Prec == k_PropVar_TimePrec_HighPrec) + return 9; + if (Prec == k_PropVar_TimePrec_0) + return 7; + int digits = (int)Prec - (int)k_PropVar_TimePrec_Base; + if (digits < 0) + digits = 0; + return digits; + } + + void Write_To_FiTime(CFiTime &dest) const + { + #ifdef _WIN32 + dest = FT; + #else + if (FILETIME_To_timespec(FT, dest)) + if ((Prec == k_PropVar_TimePrec_Base + 8 || + Prec == k_PropVar_TimePrec_Base + 9) + && Ns100 != 0) + { + dest.tv_nsec += Ns100; + } + #endif + } + + // (Def) is not set + void Set_From_FILETIME(const FILETIME &ft) + { + FT = ft; + // Prec = k_PropVar_TimePrec_CompatNTFS; + Prec = k_PropVar_TimePrec_Base + 7; + Ns100 = 0; + } + + // (Def) is not set + // it set full form precision: k_PropVar_TimePrec_Base + numDigits + void Set_From_FiTime(const CFiTime &ts) + { + #ifdef _WIN32 + FT = ts; + Prec = k_PropVar_TimePrec_Base + 7; + // Prec = k_PropVar_TimePrec_Base; // for debug + // Prec = 0; // for debug + Ns100 = 0; + #else + unsigned ns100; + FiTime_To_FILETIME_ns100(ts, FT, ns100); + Ns100 = (Byte)ns100; + Prec = k_PropVar_TimePrec_Base + 9; + #endif + } + + void Set_From_Prop(const PROPVARIANT &prop) + { + FT = prop.filetime; + unsigned prec = 0; + unsigned ns100 = 0; + const unsigned prec_Temp = prop.wReserved1; + if (prec_Temp != 0 + && prec_Temp <= k_PropVar_TimePrec_1ns + && prop.wReserved3 == 0) + { + const unsigned ns100_Temp = prop.wReserved2; + if (ns100_Temp < 100) + { + ns100 = ns100_Temp; + prec = prec_Temp; + } + } + Prec = (UInt16)prec; + Ns100 = (Byte)ns100; + Def = true; + } +}; + + +struct CDirItem: public NWindows::NFile::NFind::CFileInfoBase { - UInt64 Size; - FILETIME CTime; - FILETIME ATime; - FILETIME MTime; UString Name; - #if defined(_WIN32) && !defined(UNDER_CE) - // UString ShortName; + #ifndef UNDER_CE CByteBuffer ReparseData; - CByteBuffer ReparseData2; // fixed (reduced) absolute links + #ifdef _WIN32 + // UString ShortName; + CByteBuffer ReparseData2; // fixed (reduced) absolute links for WIM format bool AreReparseData() const { return ReparseData.Size() != 0 || ReparseData2.Size() != 0; } - #endif + #else + bool AreReparseData() const { return ReparseData.Size() != 0; } + #endif // _WIN32 + + #endif // !UNDER_CE - UInt32 Attrib; + void Copy_From_FileInfoBase(const NWindows::NFile::NFind::CFileInfoBase &fi) + { + (NWindows::NFile::NFind::CFileInfoBase &)*this = fi; + } + int PhyParent; int LogParent; int SecureIndex; - bool IsAltStream; - - CDirItem(): PhyParent(-1), LogParent(-1), SecureIndex(-1), IsAltStream(false) {} - bool IsDir() const { return (Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0 ; } + #ifdef _WIN32 + #else + int OwnerNameIndex; + int OwnerGroupIndex; + #endif + + CDirItem(): + PhyParent(-1) + , LogParent(-1) + , SecureIndex(-1) + #ifdef _WIN32 + #else + , OwnerNameIndex(-1) + , OwnerGroupIndex(-1) + #endif + { + } + + + CDirItem(const NWindows::NFile::NFind::CFileInfo &fi, + int phyParent, int logParent, int secureIndex): + CFileInfoBase(fi) + , Name(fs2us(fi.Name)) + #if defined(_WIN32) && !defined(UNDER_CE) + // , ShortName(fs2us(fi.ShortName)) + #endif + , PhyParent(phyParent) + , LogParent(logParent) + , SecureIndex(secureIndex) + #ifdef _WIN32 + #else + , OwnerNameIndex(-1) + , OwnerGroupIndex(-1) + #endif + {} }; + + class CDirItems { UStringVector Prefixes; @@ -84,18 +307,26 @@ public: CObjectVector<CDirItem> Items; bool SymLinks; - bool ScanAltStreams; - + bool ExcludeDirItems; + bool ExcludeFileItems; + bool ShareForWrite; + + /* it must be called after anotrher checks */ + bool CanIncludeItem(bool isDir) const + { + return isDir ? !ExcludeDirItems : !ExcludeFileItems; + } + + CDirItemsStat Stat; - #ifndef UNDER_CE + #if !defined(UNDER_CE) HRESULT SetLinkInfo(CDirItem &dirItem, const NWindows::NFile::NFind::CFileInfo &fi, const FString &phyPrefix); #endif - - #if defined(_WIN32) && !defined(UNDER_CE) + #if defined(_WIN32) && !defined(UNDER_CE) CUniqBlocks SecureBlocks; CByteBuffer TempSecureBuf; @@ -103,8 +334,19 @@ public: bool ReadSecure; HRESULT AddSecurityItem(const FString &path, int &secureIndex); + HRESULT FillFixedReparse(); - #endif + #endif + + #ifndef _WIN32 + + C_UInt32_UString_Map OwnerNameMap; + C_UInt32_UString_Map OwnerGroupMap; + bool StoreOwnerName; + + HRESULT FillDeviceSizes(); + + #endif IDirItemsCallback *Callback; @@ -124,6 +366,9 @@ public: unsigned AddPrefix(int phyParent, int logParent, const UString &prefix); void DeleteLastPrefix(); + + // HRESULT EnumerateOneDir(const FString &phyPrefix, CObjectVector<NWindows::NFile::NFind::CDirEntry> &files); + HRESULT EnumerateOneDir(const FString &phyPrefix, CObjectVector<NWindows::NFile::NFind::CFileInfo> &files); HRESULT EnumerateItems2( const FString &phyPrefix, @@ -131,27 +376,29 @@ public: const FStringVector &filePaths, FStringVector *requestedPaths); - #if defined(_WIN32) && !defined(UNDER_CE) - void FillFixedReparse(); - #endif - void ReserveDown(); }; + + + struct CArcItem { UInt64 Size; - FILETIME MTime; UString Name; + CArcTime MTime; // it can be mtime of archive file, if MTime is not defined for item in archive bool IsDir; bool IsAltStream; - bool SizeDefined; - bool MTimeDefined; + bool Size_Defined; bool Censored; UInt32 IndexInServer; - int TimeType; - CArcItem(): IsDir(false), IsAltStream(false), SizeDefined(false), MTimeDefined(false), Censored(false), TimeType(-1) {} + CArcItem(): + IsDir(false), + IsAltStream(false), + Size_Defined(false), + Censored(false) + {} }; #endif diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/EnumDirItems.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/EnumDirItems.cpp index 3ebf25aad8f..d536c4739aa 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/EnumDirItems.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Common/EnumDirItems.cpp @@ -3,6 +3,13 @@ #include "StdAfx.h" #include <wchar.h> +// #include <stdio.h> + +#ifndef _WIN32 +#include <grp.h> +#include <pwd.h> +#include "../../../Common/UTFConvert.h" +#endif #include "../../../Common/Wildcard.h" @@ -11,42 +18,71 @@ #include "../../../Windows/FileName.h" #if defined(_WIN32) && !defined(UNDER_CE) -#define _USE_SECURITY_CODE +#define Z7_USE_SECURITY_CODE #include "../../../Windows/SecurityUtils.h" #endif #include "EnumDirItems.h" +#include "SortUtils.h" using namespace NWindows; using namespace NFile; using namespace NName; + +static bool FindFile_KeepDots(NFile::NFind::CFileInfo &fi, const FString &path, bool followLink) +{ + const bool res = fi.Find(path, followLink); + if (!res) + return res; + if (path.IsEmpty()) + return res; + // we keep name "." and "..", if it's without tail slash + const FChar *p = path.RightPtr(1); + if (*p != '.') + return res; + if (p != path.Ptr()) + { + FChar c = p[-1]; + if (!IS_PATH_SEPAR(c)) + { + if (c != '.') + return res; + p--; + if (p != path.Ptr()) + { + c = p[-1]; + if (!IS_PATH_SEPAR(c)) + return res; + } + } + } + fi.Name = p; + return res; +} + + void CDirItems::AddDirFileInfo(int phyParent, int logParent, int secureIndex, const NFind::CFileInfo &fi) { - CDirItem di; - di.Size = fi.Size; - di.CTime = fi.CTime; - di.ATime = fi.ATime; - di.MTime = fi.MTime; - di.Attrib = fi.Attrib; - di.IsAltStream = fi.IsAltStream; + /* + CDirItem di(fi); di.PhyParent = phyParent; di.LogParent = logParent; di.SecureIndex = secureIndex; - di.Name = fs2us(fi.Name); - #if defined(_WIN32) && !defined(UNDER_CE) - // di.ShortName = fs2us(fi.ShortName); - #endif Items.Add(di); + */ + VECTOR_ADD_NEW_OBJECT (Items, CDirItem(fi, phyParent, logParent, secureIndex)) if (fi.IsDir()) Stat.NumDirs++; + #ifdef _WIN32 else if (fi.IsAltStream) { Stat.NumAltStreams++; Stat.AltStreamsSize += fi.Size; } + #endif else { Stat.NumFiles++; @@ -54,8 +90,13 @@ void CDirItems::AddDirFileInfo(int phyParent, int logParent, int secureIndex, } } +// (DWORD)E_FAIL +#define DI_DEFAULT_ERROR ERROR_INVALID_FUNCTION + HRESULT CDirItems::AddError(const FString &path, DWORD errorCode) { + if (errorCode == 0) + errorCode = DI_DEFAULT_ERROR; Stat.NumErrors++; if (Callback) return Callback->ScanError(path, errorCode); @@ -82,17 +123,17 @@ UString CDirItems::GetPrefixesPath(const CIntVector &parents, int index, const U unsigned len = name.Len(); int i; - for (i = index; i >= 0; i = parents[i]) - len += Prefixes[i].Len(); + for (i = index; i >= 0; i = parents[(unsigned)i]) + len += Prefixes[(unsigned)i].Len(); wchar_t *p = path.GetBuf_SetEnd(len) + len; p -= name.Len(); wmemcpy(p, (const wchar_t *)name, name.Len()); - for (i = index; i >= 0; i = parents[i]) + for (i = index; i >= 0; i = parents[(unsigned)i]) { - const UString &s = Prefixes[i]; + const UString &s = Prefixes[(unsigned)i]; p -= s.Len(); wmemcpy(p, (const wchar_t *)s, s.Len()); } @@ -139,17 +180,24 @@ bool InitLocalPrivileges(); CDirItems::CDirItems(): SymLinks(false), ScanAltStreams(false) - #ifdef _USE_SECURITY_CODE + , ExcludeDirItems(false) + , ExcludeFileItems(false) + , ShareForWrite(false) + #ifdef Z7_USE_SECURITY_CODE , ReadSecure(false) - #endif + #endif + #ifndef _WIN32 + , StoreOwnerName(false) + #endif , Callback(NULL) { - #ifdef _USE_SECURITY_CODE + #ifdef Z7_USE_SECURITY_CODE _saclEnabled = InitLocalPrivileges(); #endif } -#ifdef _USE_SECURITY_CODE + +#ifdef Z7_USE_SECURITY_CODE HRESULT CDirItems::AddSecurityItem(const FString &path, int &secureIndex) { @@ -165,7 +213,7 @@ HRESULT CDirItems::AddSecurityItem(const FString &path, int &secureIndex) DWORD errorCode = 0; DWORD secureSize; - BOOL res = ::GetFileSecurityW(fs2us(path), securInfo, (PSECURITY_DESCRIPTOR)(Byte *)TempSecureBuf, (DWORD)TempSecureBuf.Size(), &secureSize); + BOOL res = ::GetFileSecurityW(fs2us(path), securInfo, (PSECURITY_DESCRIPTOR)(void *)(Byte *)TempSecureBuf, (DWORD)TempSecureBuf.Size(), &secureSize); if (res) { @@ -184,11 +232,11 @@ HRESULT CDirItems::AddSecurityItem(const FString &path, int &secureIndex) else { TempSecureBuf.Alloc(secureSize); - res = ::GetFileSecurityW(fs2us(path), securInfo, (PSECURITY_DESCRIPTOR)(Byte *)TempSecureBuf, (DWORD)TempSecureBuf.Size(), &secureSize); + res = ::GetFileSecurityW(fs2us(path), securInfo, (PSECURITY_DESCRIPTOR)(void *)(Byte *)TempSecureBuf, (DWORD)TempSecureBuf.Size(), &secureSize); if (res) { if (secureSize != TempSecureBuf.Size()) - errorCode = ERROR_INVALID_FUNCTION;; + errorCode = ERROR_INVALID_FUNCTION; } else errorCode = GetLastError(); @@ -198,103 +246,224 @@ HRESULT CDirItems::AddSecurityItem(const FString &path, int &secureIndex) if (res) { - secureIndex = SecureBlocks.AddUniq(TempSecureBuf, secureSize); + secureIndex = (int)SecureBlocks.AddUniq(TempSecureBuf, secureSize); return S_OK; } - if (errorCode == 0) - errorCode = ERROR_INVALID_FUNCTION; return AddError(path, errorCode); } -#endif +#endif // Z7_USE_SECURITY_CODE -HRESULT CDirItems::EnumerateDir(int phyParent, int logParent, const FString &phyPrefix) + +HRESULT CDirItems::EnumerateOneDir(const FString &phyPrefix, CObjectVector<NFind::CFileInfo> &files) { - RINOK(ScanProgress(phyPrefix)); + NFind::CEnumerator enumerator; + // printf("\n enumerator.SetDirPrefix(phyPrefix) \n"); + + enumerator.SetDirPrefix(phyPrefix); + + #ifdef _WIN32 + + NFind::CFileInfo fi; - NFind::CEnumerator enumerator(phyPrefix + FCHAR_ANY_MASK); for (unsigned ttt = 0; ; ttt++) { - NFind::CFileInfo fi; bool found; if (!enumerator.Next(fi, found)) + return AddError(phyPrefix); + if (!found) + return S_OK; + files.Add(fi); + if (Callback && (ttt & kScanProgressStepMask) == kScanProgressStepMask) + { + RINOK(ScanProgress(phyPrefix)) + } + } + + #else // _WIN32 + + // enumerator.SolveLinks = !SymLinks; + + CObjectVector<NFind::CDirEntry> entries; + + for (unsigned ttt = 0; ; ttt++) + { + bool found; + NFind::CDirEntry de; + if (!enumerator.Next(de, found)) { return AddError(phyPrefix); } if (!found) - return S_OK; + break; + entries.Add(de); + } + + FOR_VECTOR(i, entries) + { + const NFind::CDirEntry &de = entries[i]; + NFind::CFileInfo fi; + if (!enumerator.Fill_FileInfo(de, fi, !SymLinks)) + // if (!fi.Find_AfterEnumerator(path)) + { + const FString path = phyPrefix + de.Name; + { + RINOK(AddError(path)) + continue; + } + } + + files.Add(fi); + + if (Callback && (i & kScanProgressStepMask) == kScanProgressStepMask) + { + RINOK(ScanProgress(phyPrefix)) + } + } + + return S_OK; + + #endif // _WIN32 +} + + + + +HRESULT CDirItems::EnumerateDir(int phyParent, int logParent, const FString &phyPrefix) +{ + RINOK(ScanProgress(phyPrefix)) + + CObjectVector<NFind::CFileInfo> files; + RINOK(EnumerateOneDir(phyPrefix, files)) + FOR_VECTOR (i, files) + { + #ifdef _WIN32 + const NFind::CFileInfo &fi = files[i]; + #else + const NFind::CFileInfo &fi = files[i]; + /* + NFind::CFileInfo fi; + { + const NFind::CDirEntry &di = files[i]; + const FString path = phyPrefix + di.Name; + if (!fi.Find_AfterEnumerator(path)) + { + RINOK(AddError(path)); + continue; + } + fi.Name = di.Name; + } + */ + #endif + + if (CanIncludeItem(fi.IsDir())) + { int secureIndex = -1; - #ifdef _USE_SECURITY_CODE + #ifdef Z7_USE_SECURITY_CODE if (ReadSecure) { - RINOK(AddSecurityItem(phyPrefix + fi.Name, secureIndex)); + RINOK(AddSecurityItem(phyPrefix + fi.Name, secureIndex)) } #endif - AddDirFileInfo(phyParent, logParent, secureIndex, fi); + } - if (Callback && (ttt & kScanProgressStepMask) == kScanProgressStepMask) + if (Callback && (i & kScanProgressStepMask) == kScanProgressStepMask) { - RINOK(ScanProgress(phyPrefix)); + RINOK(ScanProgress(phyPrefix)) } if (fi.IsDir()) { const FString name2 = fi.Name + FCHAR_PATH_SEPARATOR; unsigned parent = AddPrefix(phyParent, logParent, fs2us(name2)); - RINOK(EnumerateDir(parent, parent, phyPrefix + name2)); + RINOK(EnumerateDir((int)parent, (int)parent, phyPrefix + name2)) } } + return S_OK; } + +/* +EnumerateItems2() + const FStringVector &filePaths - are path without tail slashes. + All dir prefixes of filePaths will be not stores in logical paths +fix it: we can scan AltStream also. +*/ + +#ifdef _WIN32 +// #define FOLLOW_LINK_PARAM +// #define FOLLOW_LINK_PARAM2 +#define FOLLOW_LINK_PARAM , (!SymLinks) +#define FOLLOW_LINK_PARAM2 , (!dirItems.SymLinks) +#else +#define FOLLOW_LINK_PARAM , (!SymLinks) +#define FOLLOW_LINK_PARAM2 , (!dirItems.SymLinks) +#endif + HRESULT CDirItems::EnumerateItems2( const FString &phyPrefix, const UString &logPrefix, const FStringVector &filePaths, FStringVector *requestedPaths) { - int phyParent = phyPrefix.IsEmpty() ? -1 : AddPrefix(-1, -1, fs2us(phyPrefix)); - int logParent = logPrefix.IsEmpty() ? -1 : AddPrefix(-1, -1, logPrefix); + const int phyParent = phyPrefix.IsEmpty() ? -1 : (int)AddPrefix(-1, -1, fs2us(phyPrefix)); + const int logParent = logPrefix.IsEmpty() ? -1 : (int)AddPrefix(-1, -1, logPrefix); + + #ifdef _WIN32 + const bool phyPrefix_isAltStreamPrefix = + NFile::NName::IsAltStreamPrefixWithColon(fs2us(phyPrefix)); + #endif FOR_VECTOR (i, filePaths) { const FString &filePath = filePaths[i]; NFind::CFileInfo fi; const FString phyPath = phyPrefix + filePath; - if (!fi.Find(phyPath)) + if (!FindFile_KeepDots(fi, phyPath FOLLOW_LINK_PARAM)) { - RINOK(AddError(phyPath)); + RINOK(AddError(phyPath)) continue; } if (requestedPaths) requestedPaths->Add(phyPath); - int delimiter = filePath.ReverseFind_PathSepar(); + const int delimiter = filePath.ReverseFind_PathSepar(); FString phyPrefixCur; int phyParentCur = phyParent; if (delimiter >= 0) { - phyPrefixCur.SetFrom(filePath, delimiter + 1); - phyParentCur = AddPrefix(phyParent, logParent, fs2us(phyPrefixCur)); + phyPrefixCur.SetFrom(filePath, (unsigned)(delimiter + 1)); + phyParentCur = (int)AddPrefix(phyParent, logParent, fs2us(phyPrefixCur)); } + if (CanIncludeItem(fi.IsDir())) + { int secureIndex = -1; - #ifdef _USE_SECURITY_CODE + #ifdef Z7_USE_SECURITY_CODE if (ReadSecure) { - RINOK(AddSecurityItem(phyPath, secureIndex)); + RINOK(AddSecurityItem(phyPath, secureIndex)) } #endif - + #ifdef _WIN32 + if (phyPrefix_isAltStreamPrefix && fi.IsAltStream) + { + const int pos = fi.Name.Find(FChar(':')); + if (pos >= 0) + fi.Name.DeleteFrontal((unsigned)pos + 1); + } + #endif AddDirFileInfo(phyParentCur, logParent, secureIndex, fi); + } if (fi.IsDir()) { const FString name2 = fi.Name + FCHAR_PATH_SEPARATOR; - unsigned parent = AddPrefix(phyParentCur, logParent, fs2us(name2)); - RINOK(EnumerateDir(parent, parent, phyPrefix + phyPrefixCur + name2)); + const unsigned parent = AddPrefix(phyParentCur, logParent, fs2us(name2)); + RINOK(EnumerateDir((int)parent, (int)parent, phyPrefix + phyPrefixCur + name2)) } } @@ -305,34 +474,46 @@ HRESULT CDirItems::EnumerateItems2( - - static HRESULT EnumerateDirItems( const NWildcard::CCensorNode &curNode, - int phyParent, int logParent, const FString &phyPrefix, - const UStringVector &addArchivePrefix, + const int phyParent, const int logParent, + const FString &phyPrefix, + const UStringVector &addParts, // additional parts from curNode CDirItems &dirItems, bool enterToSubFolders); + +/* EnumerateDirItems_Spec() + adds new Dir item prefix, and enumerates dir items, + then it can remove that Dir item prefix, if there are no items in that dir. +*/ + + +/* + EnumerateDirItems_Spec() + it's similar to EnumerateDirItems, but phyPrefix doesn't include (curFolderName) +*/ + static HRESULT EnumerateDirItems_Spec( const NWildcard::CCensorNode &curNode, - int phyParent, int logParent, const FString &curFolderName, - const FString &phyPrefix, - const UStringVector &addArchivePrefix, + const int phyParent, const int logParent, const FString &curFolderName, + const FString &phyPrefix, // without (curFolderName) + const UStringVector &addParts, // (curNode + addParts) includes (curFolderName) CDirItems &dirItems, bool enterToSubFolders) { const FString name2 = curFolderName + FCHAR_PATH_SEPARATOR; - unsigned parent = dirItems.AddPrefix(phyParent, logParent, fs2us(name2)); - unsigned numItems = dirItems.Items.Size(); + const unsigned parent = dirItems.AddPrefix(phyParent, logParent, fs2us(name2)); + const unsigned numItems = dirItems.Items.Size(); HRESULT res = EnumerateDirItems( - curNode, parent, parent, phyPrefix + name2, - addArchivePrefix, dirItems, enterToSubFolders); + curNode, (int)parent, (int)parent, phyPrefix + name2, + addParts, dirItems, enterToSubFolders); if (numItems == dirItems.Items.Size()) dirItems.DeleteLastPrefix(); return res; } + #ifndef UNDER_CE #ifdef _WIN32 @@ -340,136 +521,222 @@ static HRESULT EnumerateDirItems_Spec( static HRESULT EnumerateAltStreams( const NFind::CFileInfo &fi, const NWildcard::CCensorNode &curNode, - int phyParent, int logParent, const FString &fullPath, - const UStringVector &addArchivePrefix, // prefix from curNode + const int phyParent, const int logParent, + const FString &phyPath, // with (fi.Name), without tail slash for folders + const UStringVector &addParts, // with (fi.Name), prefix parts from curNode + bool addAllSubStreams, CDirItems &dirItems) { - NFind::CStreamEnumerator enumerator(fullPath); + // we don't use (ExcludeFileItems) rules for AltStreams + // if (dirItems.ExcludeFileItems) return S_OK; + + NFind::CStreamEnumerator enumerator(phyPath); for (;;) { NFind::CStreamInfo si; bool found; if (!enumerator.Next(si, found)) { - return dirItems.AddError(fullPath + FTEXT(":*")); // , (DWORD)E_FAIL + return dirItems.AddError(phyPath + FTEXT(":*")); // , (DWORD)E_FAIL } if (!found) return S_OK; if (si.IsMainStream()) continue; - UStringVector addArchivePrefixNew = addArchivePrefix; - UString reducedName = si.GetReducedName(); - addArchivePrefixNew.Back() += reducedName; - if (curNode.CheckPathToRoot(false, addArchivePrefixNew, true)) + UStringVector parts = addParts; + const UString reducedName = si.GetReducedName(); + parts.Back() += reducedName; + if (curNode.CheckPathToRoot(false, parts, true)) continue; + if (!addAllSubStreams) + if (!curNode.CheckPathToRoot(true, parts, true)) + continue; + NFind::CFileInfo fi2 = fi; fi2.Name += us2fs(reducedName); fi2.Size = si.Size; - fi2.Attrib &= ~FILE_ATTRIBUTE_DIRECTORY; + fi2.Attrib &= ~(DWORD)(FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT); fi2.IsAltStream = true; dirItems.AddDirFileInfo(phyParent, logParent, -1, fi2); } } -#endif +#endif // _WIN32 + + +/* We get Reparse data and parse it. + If there is Reparse error, we free dirItem.Reparse data. + Do we need to work with empty reparse data? +*/ HRESULT CDirItems::SetLinkInfo(CDirItem &dirItem, const NFind::CFileInfo &fi, const FString &phyPrefix) { - if (!SymLinks || !fi.HasReparsePoint()) + if (!SymLinks) return S_OK; + + #ifdef _WIN32 + if (!fi.HasReparsePoint() || fi.IsAltStream) + #else // _WIN32 + if (!fi.IsPosixLink()) + #endif // _WIN32 + return S_OK; + const FString path = phyPrefix + fi.Name; CByteBuffer &buf = dirItem.ReparseData; if (NIO::GetReparseData(path, buf)) { - CReparseAttr attr; - if (attr.Parse(buf, buf.Size())) - return S_OK; + // if (dirItem.ReparseData.Size() != 0) + Stat.FilesSize -= fi.Size; + return S_OK; } + DWORD res = ::GetLastError(); buf.Free(); - return AddError(path , res); + return AddError(path, res); } -#endif +#endif // UNDER_CE + + static HRESULT EnumerateForItem( - NFind::CFileInfo &fi, + const NFind::CFileInfo &fi, const NWildcard::CCensorNode &curNode, - int phyParent, int logParent, const FString &phyPrefix, - const UStringVector &addArchivePrefix, // prefix from curNode + const int phyParent, const int logParent, const FString &phyPrefix, + const UStringVector &addParts, // additional parts from curNode, without (fi.Name) CDirItems &dirItems, bool enterToSubFolders) { const UString name = fs2us(fi.Name); - bool enterToSubFolders2 = enterToSubFolders; - UStringVector addArchivePrefixNew = addArchivePrefix; - addArchivePrefixNew.Add(name); - { - UStringVector addArchivePrefixNewTemp(addArchivePrefixNew); - if (curNode.CheckPathToRoot(false, addArchivePrefixNewTemp, !fi.IsDir())) - return S_OK; - } - int dirItemIndex = -1; + UStringVector newParts = addParts; + newParts.Add(name); - if (curNode.CheckPathToRoot(true, addArchivePrefixNew, !fi.IsDir())) + // check the path in exclude rules + if (curNode.CheckPathToRoot(false, newParts, !fi.IsDir())) + return S_OK; + + #if !defined(UNDER_CE) + int dirItemIndex = -1; + #if defined(_WIN32) + bool addAllSubStreams = false; + bool needAltStreams = true; + #endif // _WIN32 + #endif // !defined(UNDER_CE) + + // check the path in inlcude rules + if (curNode.CheckPathToRoot(true, newParts, !fi.IsDir())) { - int secureIndex = -1; - #ifdef _USE_SECURITY_CODE - if (dirItems.ReadSecure) + #if !defined(UNDER_CE) + // dirItemIndex = (int)dirItems.Items.Size(); + #if defined(_WIN32) + // we will not check include rules for substreams. + addAllSubStreams = true; + #endif // _WIN32 + #endif // !defined(UNDER_CE) + + if (dirItems.CanIncludeItem(fi.IsDir())) { - RINOK(dirItems.AddSecurityItem(phyPrefix + fi.Name, secureIndex)); - } + int secureIndex = -1; + #ifdef Z7_USE_SECURITY_CODE + if (dirItems.ReadSecure) + { + RINOK(dirItems.AddSecurityItem(phyPrefix + fi.Name, secureIndex)) + } #endif + #if !defined(UNDER_CE) + dirItemIndex = (int)dirItems.Items.Size(); + #endif // !defined(UNDER_CE) + dirItems.AddDirFileInfo(phyParent, logParent, secureIndex, fi); + } + else + { + #if defined(_WIN32) && !defined(UNDER_CE) + needAltStreams = false; + #endif + } - dirItemIndex = dirItems.Items.Size(); - dirItems.AddDirFileInfo(phyParent, logParent, secureIndex, fi); if (fi.IsDir()) - enterToSubFolders2 = true; + enterToSubFolders = true; } - #ifndef UNDER_CE - if (dirItems.ScanAltStreams) - { - RINOK(EnumerateAltStreams(fi, curNode, phyParent, logParent, - phyPrefix + fi.Name, - addArchivePrefixNew, dirItems)); - } + #if !defined(UNDER_CE) + + // we don't scan AltStreams for link files if (dirItemIndex >= 0) { - CDirItem &dirItem = dirItems.Items[dirItemIndex]; - RINOK(dirItems.SetLinkInfo(dirItem, fi, phyPrefix)); + CDirItem &dirItem = dirItems.Items[(unsigned)dirItemIndex]; + RINOK(dirItems.SetLinkInfo(dirItem, fi, phyPrefix)) if (dirItem.ReparseData.Size() != 0) return S_OK; } - #endif + #if defined(_WIN32) + if (needAltStreams && dirItems.ScanAltStreams) + { + RINOK(EnumerateAltStreams(fi, curNode, phyParent, logParent, + phyPrefix + fi.Name, // with (fi.Name) + newParts, // with (fi.Name) + addAllSubStreams, + dirItems)) + } + #endif + + #endif // !defined(UNDER_CE) + + + #ifndef _WIN32 + if (!fi.IsPosixLink()) // posix link can follow to dir + #endif if (!fi.IsDir()) return S_OK; - - const NWildcard::CCensorNode *nextNode = 0; - if (addArchivePrefix.IsEmpty()) + + const NWildcard::CCensorNode *nextNode = NULL; + + if (addParts.IsEmpty()) { int index = curNode.FindSubNode(name); if (index >= 0) - nextNode = &curNode.SubNodes[index]; + { + nextNode = &curNode.SubNodes[(unsigned)index]; + newParts.Clear(); + } } - if (!enterToSubFolders2 && nextNode == 0) - return S_OK; - - addArchivePrefixNew = addArchivePrefix; - if (nextNode == 0) + + if (!nextNode) { + if (!enterToSubFolders) + return S_OK; + + #ifndef _WIN32 + if (fi.IsPosixLink()) + { + // here we can try to resolve posix link + // if the link to dir, then can we follow it + return S_OK; // we don't follow posix link + } + #else + if (dirItems.SymLinks && fi.HasReparsePoint()) + { + /* 20.03: in SymLinks mode: we don't enter to directory that + has reparse point and has no CCensorNode + NOTE: (curNode and parent nodes) still can have wildcard rules + to include some items of target directory (of reparse point), + but we ignore these rules here. + */ + return S_OK; + } + #endif nextNode = &curNode; - addArchivePrefixNew.Add(name); } return EnumerateDirItems_Spec( - *nextNode, phyParent, logParent, fi.Name, phyPrefix, - addArchivePrefixNew, + *nextNode, phyParent, logParent, fi.Name, + phyPrefix, // without (fi.Name) + newParts, // relative to (*nextNode). (*nextNode + newParts) includes (fi.Name) dirItems, - enterToSubFolders2); + enterToSubFolders); } @@ -488,10 +755,13 @@ static bool CanUseFsDirect(const NWildcard::CCensorNode &curNode) /* Windows doesn't support file name with wildcard But if another system supports file name with wildcard, - and wildcard mode is disabled, we can ignore wildcard in name */ + and wildcard mode is disabled, we can ignore wildcard in name + */ /* + #ifndef _WIN32 if (!item.WildcardParsing) continue; + #endif */ if (DoesNameContainWildcard(name)) return false; @@ -507,26 +777,33 @@ static bool IsVirtualFsFolder(const FString &prefix, const UString &name) UString s = fs2us(prefix); s += name; s.Add_PathSepar(); + // it returns (true) for non real FS folder path like - "\\SERVER\" return IsPathSepar(s[0]) && GetRootPrefixSize(s) == 0; } #endif + + static HRESULT EnumerateDirItems( const NWildcard::CCensorNode &curNode, - int phyParent, int logParent, const FString &phyPrefix, - const UStringVector &addArchivePrefix, // prefix from curNode + const int phyParent, const int logParent, const FString &phyPrefix, + const UStringVector &addParts, // prefix from curNode including CDirItems &dirItems, bool enterToSubFolders) { if (!enterToSubFolders) + { + /* if there are IncludeItems censor rules that affect items in subdirs, + then we will enter to all subfolders */ if (curNode.NeedCheckSubDirs()) enterToSubFolders = true; + } - RINOK(dirItems.ScanProgress(phyPrefix)); + RINOK(dirItems.ScanProgress(phyPrefix)) // try direct_names case at first - if (addArchivePrefix.IsEmpty() && !enterToSubFolders) + if (addParts.IsEmpty() && !enterToSubFolders) { if (CanUseFsDirect(curNode)) { @@ -541,11 +818,20 @@ static HRESULT EnumerateDirItems( const UString &name = item.PathParts.Front(); FString fullPath = phyPrefix + us2fs(name); + /* + // not possible now + if (!item.ForDir && !item.ForFile) + { + RINOK(dirItems.AddError(fullPath, ERROR_INVALID_PARAMETER)); + continue; + } + */ + #if defined(_WIN32) && !defined(UNDER_CE) bool needAltStreams = true; #endif - #ifdef _USE_SECURITY_CODE + #ifdef Z7_USE_SECURITY_CODE bool needSecurity = true; #endif @@ -565,12 +851,12 @@ static HRESULT EnumerateDirItems( /* // do we need to ignore security info for "\\" folder ? - #ifdef _USE_SECURITY_CODE + #ifdef Z7_USE_SECURITY_CODE needSecurity = false; #endif */ - fullPath = FCHAR_PATH_SEPARATOR; + fullPath = CHAR_PATH_SEPARATOR; } #if defined(_WIN32) && !defined(UNDER_CE) else if (item.IsDriveItem()) @@ -591,16 +877,27 @@ static HRESULT EnumerateDirItems( } else #endif - if (!fi.Find(fullPath)) + if (!FindFile_KeepDots(fi, fullPath FOLLOW_LINK_PARAM2)) { - RINOK(dirItems.AddError(fullPath)); + RINOK(dirItems.AddError(fullPath)) continue; } - bool isDir = fi.IsDir(); - if (isDir && !item.ForDir || !isDir && !item.ForFile) + /* + #ifdef _WIN32 + #define MY_ERROR_IS_DIR ERROR_FILE_NOT_FOUND + #define MY_ERROR_NOT_DIR DI_DEFAULT_ERROR + #else + #define MY_ERROR_IS_DIR EISDIR + #define MY_ERROR_NOT_DIR ENOTDIR + #endif + */ + + const bool isDir = fi.IsDir(); + if (isDir ? !item.ForDir : !item.ForFile) { - RINOK(dirItems.AddError(fullPath, (DWORD)E_FAIL)); + // RINOK(dirItems.AddError(fullPath, isDir ? MY_ERROR_IS_DIR: MY_ERROR_NOT_DIR)); + RINOK(dirItems.AddError(fullPath, DI_DEFAULT_ERROR)) continue; } { @@ -610,65 +907,90 @@ static HRESULT EnumerateDirItems( continue; } + + if (dirItems.CanIncludeItem(fi.IsDir())) + { int secureIndex = -1; - #ifdef _USE_SECURITY_CODE + #ifdef Z7_USE_SECURITY_CODE if (needSecurity && dirItems.ReadSecure) { - RINOK(dirItems.AddSecurityItem(fullPath, secureIndex)); + RINOK(dirItems.AddSecurityItem(fullPath, secureIndex)) } #endif dirItems.AddDirFileInfo(phyParent, logParent, secureIndex, fi); - #ifndef UNDER_CE + // we don't scan AltStreams for link files + + #if !defined(UNDER_CE) { CDirItem &dirItem = dirItems.Items.Back(); - RINOK(dirItems.SetLinkInfo(dirItem, fi, phyPrefix)); + RINOK(dirItems.SetLinkInfo(dirItem, fi, phyPrefix)) if (dirItem.ReparseData.Size() != 0) - { - if (fi.IsAltStream) - dirItems.Stat.AltStreamsSize -= fi.Size; - else - dirItems.Stat.FilesSize -= fi.Size; continue; - } } - #endif - - - #ifndef UNDER_CE + + #if defined(_WIN32) if (needAltStreams && dirItems.ScanAltStreams) { UStringVector pathParts; pathParts.Add(fs2us(fi.Name)); RINOK(EnumerateAltStreams(fi, curNode, phyParent, logParent, - fullPath, pathParts, dirItems)); + fullPath, // including (name) + pathParts, // including (fi.Name) + true, /* addAllSubStreams */ + dirItems)) } - #endif + #endif // defined(_WIN32) + + #endif // !defined(UNDER_CE) + } + + #ifndef _WIN32 + if (!fi.IsPosixLink()) // posix link can follow to dir + #endif if (!isDir) continue; - - UStringVector addArchivePrefixNew; - const NWildcard::CCensorNode *nextNode = 0; + + UStringVector newParts; + const NWildcard::CCensorNode *nextNode = NULL; int index = curNode.FindSubNode(name); if (index >= 0) { - for (int t = needEnterVector.Size(); t <= index; t++) + for (int t = (int)needEnterVector.Size(); t <= index; t++) needEnterVector.Add(true); - needEnterVector[index] = false; - nextNode = &curNode.SubNodes[index]; + needEnterVector[(unsigned)index] = false; + nextNode = &curNode.SubNodes[(unsigned)index]; } else { + #ifndef _WIN32 + if (fi.IsPosixLink()) + { + // here we can try to resolve posix link + // if the link to dir, then can we follow it + continue; // we don't follow posix link + } + #else + if (dirItems.SymLinks) + { + if (fi.HasReparsePoint()) + { + /* 20.03: in SymLinks mode: we don't enter to directory that + has reparse point and has no CCensorNode */ + continue; + } + } + #endif nextNode = &curNode; - addArchivePrefixNew.Add(name); // don't change it to fi.Name. It's for shortnames support + newParts.Add(name); // don't change it to fi.Name. It's for shortnames support } RINOK(EnumerateDirItems_Spec(*nextNode, phyParent, logParent, fi.Name, phyPrefix, - addArchivePrefixNew, dirItems, true)); + newParts, dirItems, true)) } - + for (i = 0; i < curNode.SubNodes.Size(); i++) { if (i < needEnterVector.Size()) @@ -678,20 +1000,23 @@ static HRESULT EnumerateDirItems( FString fullPath = phyPrefix + us2fs(nextNode.Name); NFind::CFileInfo fi; - if (phyPrefix.IsEmpty()) + if (nextNode.Name.IsEmpty()) { - { - if (nextNode.Name.IsEmpty()) - fullPath = FCHAR_PATH_SEPARATOR; - #ifdef _WIN32 - else if (NWildcard::IsDriveColonName(nextNode.Name)) - fullPath.Add_PathSepar(); - #endif - } + if (phyPrefix.IsEmpty()) + fullPath = CHAR_PATH_SEPARATOR; } + #ifdef _WIN32 + else if(phyPrefix.IsEmpty() + || (phyPrefix.Len() == NName::kSuperPathPrefixSize + && IsSuperPath(phyPrefix))) + { + if (NWildcard::IsDriveColonName(nextNode.Name)) + fullPath.Add_PathSepar(); + } + #endif // we don't want to call fi.Find() for root folder or virtual folder - if (phyPrefix.IsEmpty() && nextNode.Name.IsEmpty() + if ((phyPrefix.IsEmpty() && nextNode.Name.IsEmpty()) #if defined(_WIN32) && !defined(UNDER_CE) || IsVirtualFsFolder(phyPrefix, nextNode.Name) #endif @@ -702,23 +1027,23 @@ static HRESULT EnumerateDirItems( } else { - if (!fi.Find(fullPath)) + if (!FindFile_KeepDots(fi, fullPath FOLLOW_LINK_PARAM2)) { if (!nextNode.AreThereIncludeItems()) continue; - RINOK(dirItems.AddError(fullPath)); + RINOK(dirItems.AddError(fullPath)) continue; } if (!fi.IsDir()) { - RINOK(dirItems.AddError(fullPath, (DWORD)E_FAIL)); + RINOK(dirItems.AddError(fullPath, DI_DEFAULT_ERROR)) continue; } } RINOK(EnumerateDirItems_Spec(nextNode, phyParent, logParent, fi.Name, phyPrefix, - UStringVector(), dirItems, false)); + UStringVector(), dirItems, false)) } return S_OK; @@ -764,7 +1089,7 @@ static HRESULT EnumerateDirItems( fi.Name = driveName; RINOK(EnumerateForItem(fi, curNode, phyParent, logParent, phyPrefix, - addArchivePrefix, dirItems, enterToSubFolders)); + addParts, dirItems, enterToSubFolders)) } return S_OK; } @@ -773,41 +1098,81 @@ static HRESULT EnumerateDirItems( #endif #endif - NFind::CEnumerator enumerator(phyPrefix + FCHAR_ANY_MASK); - for (unsigned ttt = 0; ; ttt++) + + CObjectVector<NFind::CFileInfo> files; + + // for (int y = 0; y < 1; y++) { - NFind::CFileInfo fi; - bool found; - if (!enumerator.Next(fi, found)) + // files.Clear(); + RINOK(dirItems.EnumerateOneDir(phyPrefix, files)) + /* + FOR_VECTOR (i, files) + { + #ifdef _WIN32 + // const NFind::CFileInfo &fi = files[i]; + #else + NFind::CFileInfo &fi = files[i]; { - RINOK(dirItems.AddError(phyPrefix)); - break; + const NFind::CFileInfo &di = files[i]; + const FString path = phyPrefix + di.Name; + if (!fi.Find_AfterEnumerator(path)) + { + RINOK(dirItems.AddError(path)); + continue; + } + fi.Name = di.Name; } - if (!found) - break; + #endif + + } + */ + } - if (dirItems.Callback && (ttt & kScanProgressStepMask) == kScanProgressStepMask) + FOR_VECTOR (i, files) + { + #ifdef _WIN32 + const NFind::CFileInfo &fi = files[i]; + #else + const NFind::CFileInfo &fi = files[i]; + /* + NFind::CFileInfo fi; { - RINOK(dirItems.ScanProgress(phyPrefix)); + const NFind::CDirEntry &di = files[i]; + const FString path = phyPrefix + di.Name; + if (!fi.Find_AfterEnumerator(path)) + { + RINOK(dirItems.AddError(path)); + continue; + } + fi.Name = di.Name; } + */ + #endif RINOK(EnumerateForItem(fi, curNode, phyParent, logParent, phyPrefix, - addArchivePrefix, dirItems, enterToSubFolders)); + addParts, dirItems, enterToSubFolders)) + if (dirItems.Callback && (i & kScanProgressStepMask) == kScanProgressStepMask) + { + RINOK(dirItems.ScanProgress(phyPrefix)) + } } return S_OK; } + + + HRESULT EnumerateItems( const NWildcard::CCensor &censor, const NWildcard::ECensorPathMode pathMode, - const UString &addPathPrefix, + const UString &addPathPrefix, // prefix that will be added to Logical Path CDirItems &dirItems) { FOR_VECTOR (i, censor.Pairs) { const NWildcard::CPair &pair = censor.Pairs[i]; - int phyParent = pair.Prefix.IsEmpty() ? -1 : dirItems.AddPrefix(-1, -1, pair.Prefix); + const int phyParent = pair.Prefix.IsEmpty() ? -1 : (int)dirItems.AddPrefix(-1, -1, pair.Prefix); int logParent = -1; if (pathMode == NWildcard::k_AbsPath) @@ -815,44 +1180,117 @@ HRESULT EnumerateItems( else { if (!addPathPrefix.IsEmpty()) - logParent = dirItems.AddPrefix(-1, -1, addPathPrefix); + logParent = (int)dirItems.AddPrefix(-1, -1, addPathPrefix); } RINOK(EnumerateDirItems(pair.Head, phyParent, logParent, us2fs(pair.Prefix), UStringVector(), dirItems, false // enterToSubFolders - )); + )) } dirItems.ReserveDown(); - #if defined(_WIN32) && !defined(UNDER_CE) - dirItems.FillFixedReparse(); - #endif + #if defined(_WIN32) && !defined(UNDER_CE) + RINOK(dirItems.FillFixedReparse()) + #endif + + #ifndef _WIN32 + RINOK(dirItems.FillDeviceSizes()) + #endif return S_OK; } + #if defined(_WIN32) && !defined(UNDER_CE) -void CDirItems::FillFixedReparse() +HRESULT CDirItems::FillFixedReparse() { - /* imagex/WIM reduces absolute pathes in links (raparse data), - if we archive non root folder. We do same thing here */ - - if (!SymLinks) - return; - FOR_VECTOR(i, Items) { CDirItem &item = Items[i]; + + if (!SymLinks) + { + // continue; // for debug + if (!item.Has_Attrib_ReparsePoint()) + continue; + + // if (item.IsDir()) continue; + + const FString phyPath = GetPhyPath(i); + + NFind::CFileInfo fi; + if (fi.Fill_From_ByHandleFileInfo(phyPath)) // item.IsDir() + { + item.Size = fi.Size; + item.CTime = fi.CTime; + item.ATime = fi.ATime; + item.MTime = fi.MTime; + item.Attrib = fi.Attrib; + continue; + } + + /* + // we request properties of target file instead of properies of symbolic link + // here we also can manually parse unsupported links (like WSL links) + NIO::CInFile inFile; + if (inFile.Open(phyPath)) + { + BY_HANDLE_FILE_INFORMATION info; + if (inFile.GetFileInformation(&info)) + { + // Stat.FilesSize doesn't contain item.Size already + // Stat.FilesSize -= item.Size; + item.Size = (((UInt64)info.nFileSizeHigh) << 32) + info.nFileSizeLow; + Stat.FilesSize += item.Size; + item.CTime = info.ftCreationTime; + item.ATime = info.ftLastAccessTime; + item.MTime = info.ftLastWriteTime; + item.Attrib = info.dwFileAttributes; + continue; + } + } + */ + + RINOK(AddError(phyPath)) + continue; + } + + // (SymLinks == true) here + if (item.ReparseData.Size() == 0) continue; + + // if (item.Size == 0) + { + // 20.03: we use Reparse Data instead of real data + item.Size = item.ReparseData.Size(); + } CReparseAttr attr; if (!attr.Parse(item.ReparseData, item.ReparseData.Size())) + { + const FString phyPath = GetPhyPath(i); + AddError(phyPath, attr.ErrorCode); continue; - if (attr.IsRelative()) + } + + /* imagex/WIM reduces absolute paths in links (raparse data), + if we archive non root folder. We do same thing here */ + + bool isWSL = false; + if (attr.IsSymLink_WSL()) + { + // isWSL = true; + // we don't change WSL symlinks continue; + } + else + { + if (attr.IsRelative_Win()) + continue; + } const UString &link = attr.GetPath(); if (!IsDrivePath(link)) @@ -862,7 +1300,7 @@ void CDirItems::FillFixedReparse() FString fullPathF; if (!NDir::MyGetFullPathName(GetPhyPath(i), fullPathF)) continue; - UString fullPath = fs2us(fullPathF); + const UString fullPath = fs2us(fullPathF); const UString logPath = GetLogPath(i); if (logPath.Len() >= fullPath.Len()) continue; @@ -873,7 +1311,7 @@ void CDirItems::FillFixedReparse() if (!IsPathSepar(prefix.Back())) continue; - unsigned rootPrefixSize = GetRootPrefixSize(prefix); + const unsigned rootPrefixSize = GetRootPrefixSize(prefix); if (rootPrefixSize == 0) continue; if (rootPrefixSize == prefix.Len()) @@ -889,10 +1327,330 @@ void CDirItems::FillFixedReparse() newLink += link.Ptr(prefix.Len()); CByteBuffer data; - if (!FillLinkData(data, newLink, attr.IsSymLink())) + bool isSymLink = !attr.IsMountPoint(); + if (!FillLinkData(data, newLink, isSymLink, isWSL)) continue; item.ReparseData2 = data; } + return S_OK; } #endif + + +#ifndef _WIN32 + +HRESULT CDirItems::FillDeviceSizes() +{ + { + FOR_VECTOR (i, Items) + { + CDirItem &item = Items[i]; + + if (S_ISBLK(item.mode) && item.Size == 0) + { + const FString phyPath = GetPhyPath(i); + NIO::CInFile inFile; + inFile.PreserveATime = true; + if (inFile.OpenShared(phyPath, ShareForWrite)) // fixme: OpenShared ?? + { + UInt64 size = 0; + if (inFile.GetLength(size)) + item.Size = size; + } + } + if (StoreOwnerName) + { + OwnerNameMap.Add_UInt32(item.uid); + OwnerGroupMap.Add_UInt32(item.gid); + } + } + } + + if (StoreOwnerName) + { + UString u; + AString a; + { + FOR_VECTOR (i, OwnerNameMap.Numbers) + { + // 200K/sec speed + u.Empty(); + const passwd *pw = getpwuid(OwnerNameMap.Numbers[i]); + // printf("\ngetpwuid=%s\n", pw->pw_name); + if (pw) + { + a = pw->pw_name; + ConvertUTF8ToUnicode(a, u); + } + OwnerNameMap.Strings.Add(u); + } + } + { + FOR_VECTOR (i, OwnerGroupMap.Numbers) + { + u.Empty(); + const group *gr = getgrgid(OwnerGroupMap.Numbers[i]); + if (gr) + { + // printf("\ngetgrgid %d %s\n", OwnerGroupMap.Numbers[i], gr->gr_name); + a = gr->gr_name; + ConvertUTF8ToUnicode(a, u); + } + OwnerGroupMap.Strings.Add(u); + } + } + + FOR_VECTOR (i, Items) + { + CDirItem &item = Items[i]; + { + const int index = OwnerNameMap.Find(item.uid); + if (index < 0) throw 1; + item.OwnerNameIndex = index; + } + { + const int index = OwnerGroupMap.Find(item.gid); + if (index < 0) throw 1; + item.OwnerGroupIndex = index; + } + } + } + + + // if (NeedOwnerNames) + { + /* + { + for (unsigned i = 0 ; i < 10000; i++) + { + const passwd *pw = getpwuid(i); + if (pw) + { + UString u; + ConvertUTF8ToUnicode(AString(pw->pw_name), u); + OwnerNameMap.Add(i, u); + OwnerNameMap.Add(i, u); + OwnerNameMap.Add(i, u); + } + const group *gr = getgrgid(i); + if (gr) + { + // we can use utf-8 here. + UString u; + ConvertUTF8ToUnicode(AString(gr->gr_name), u); + OwnerGroupMap.Add(i, u); + } + } + } + */ + /* + { + FOR_VECTOR (i, OwnerNameMap.Strings) + { + AString s; + ConvertUnicodeToUTF8(OwnerNameMap.Strings[i], s); + printf("\n%5d %s", (unsigned)OwnerNameMap.Numbers[i], s.Ptr()); + } + } + { + printf("\n\n=========Groups\n"); + FOR_VECTOR (i, OwnerGroupMap.Strings) + { + AString s; + ConvertUnicodeToUTF8(OwnerGroupMap.Strings[i], s); + printf("\n%5d %s", (unsigned)OwnerGroupMap.Numbers[i], s.Ptr()); + } + } + */ + } + /* + for (unsigned i = 0 ; i < 100000000; i++) + { + // const passwd *pw = getpwuid(1000); + // pw = pw; + int pos = OwnerNameMap.Find(1000); + if (pos < 0 - (int)i) + throw 1; + } + */ + + return S_OK; +} + +#endif + + + +static const char * const kCannotFindArchive = "Cannot find archive"; + +HRESULT EnumerateDirItemsAndSort( + NWildcard::CCensor &censor, + NWildcard::ECensorPathMode censorPathMode, + const UString &addPathPrefix, + UStringVector &sortedPaths, + UStringVector &sortedFullPaths, + CDirItemsStat &st, + IDirItemsCallback *callback) +{ + FStringVector paths; + + { + CDirItems dirItems; + dirItems.Callback = callback; + { + HRESULT res = EnumerateItems(censor, censorPathMode, addPathPrefix, dirItems); + st = dirItems.Stat; + RINOK(res) + } + + FOR_VECTOR (i, dirItems.Items) + { + const CDirItem &dirItem = dirItems.Items[i]; + if (!dirItem.IsDir()) + paths.Add(dirItems.GetPhyPath(i)); + } + } + + if (paths.Size() == 0) + { + // return S_OK; + throw CMessagePathException(kCannotFindArchive); + } + + UStringVector fullPaths; + + unsigned i; + + for (i = 0; i < paths.Size(); i++) + { + FString fullPath; + NFile::NDir::MyGetFullPathName(paths[i], fullPath); + fullPaths.Add(fs2us(fullPath)); + } + + CUIntVector indices; + SortFileNames(fullPaths, indices); + sortedPaths.ClearAndReserve(indices.Size()); + sortedFullPaths.ClearAndReserve(indices.Size()); + + for (i = 0; i < indices.Size(); i++) + { + unsigned index = indices[i]; + sortedPaths.AddInReserved(fs2us(paths[index])); + sortedFullPaths.AddInReserved(fullPaths[index]); + if (i > 0 && CompareFileNames(sortedFullPaths[i], sortedFullPaths[i - 1]) == 0) + throw CMessagePathException("Duplicate archive path:", sortedFullPaths[i]); + } + + return S_OK; +} + + + + +#ifdef _WIN32 + +static bool IsDotsName(const wchar_t *s) +{ + return s[0] == '.' && (s[1] == 0 || (s[1] == '.' && s[2] == 0)); +} + +// This code converts all short file names to long file names. + +static void ConvertToLongName(const UString &prefix, UString &name) +{ + if (name.IsEmpty() + || DoesNameContainWildcard(name) + || IsDotsName(name)) + return; + NFind::CFileInfo fi; + const FString path (us2fs(prefix + name)); + #ifndef UNDER_CE + if (NFile::NName::IsDevicePath(path)) + return; + #endif + if (fi.Find(path)) + name = fs2us(fi.Name); +} + +static void ConvertToLongNames(const UString &prefix, CObjectVector<NWildcard::CItem> &items) +{ + FOR_VECTOR (i, items) + { + NWildcard::CItem &item = items[i]; + if (item.Recursive || item.PathParts.Size() != 1) + continue; + if (prefix.IsEmpty() && item.IsDriveItem()) + continue; + ConvertToLongName(prefix, item.PathParts.Front()); + } +} + +static void ConvertToLongNames(const UString &prefix, NWildcard::CCensorNode &node) +{ + ConvertToLongNames(prefix, node.IncludeItems); + ConvertToLongNames(prefix, node.ExcludeItems); + unsigned i; + for (i = 0; i < node.SubNodes.Size(); i++) + { + UString &name = node.SubNodes[i].Name; + if (prefix.IsEmpty() && NWildcard::IsDriveColonName(name)) + continue; + ConvertToLongName(prefix, name); + } + // mix folders with same name + for (i = 0; i < node.SubNodes.Size(); i++) + { + NWildcard::CCensorNode &nextNode1 = node.SubNodes[i]; + for (unsigned j = i + 1; j < node.SubNodes.Size();) + { + const NWildcard::CCensorNode &nextNode2 = node.SubNodes[j]; + if (nextNode1.Name.IsEqualTo_NoCase(nextNode2.Name)) + { + nextNode1.IncludeItems += nextNode2.IncludeItems; + nextNode1.ExcludeItems += nextNode2.ExcludeItems; + node.SubNodes.Delete(j); + } + else + j++; + } + } + for (i = 0; i < node.SubNodes.Size(); i++) + { + NWildcard::CCensorNode &nextNode = node.SubNodes[i]; + ConvertToLongNames(prefix + nextNode.Name + WCHAR_PATH_SEPARATOR, nextNode); + } +} + +void ConvertToLongNames(NWildcard::CCensor &censor) +{ + FOR_VECTOR (i, censor.Pairs) + { + NWildcard::CPair &pair = censor.Pairs[i]; + ConvertToLongNames(pair.Prefix, pair.Head); + } +} + +#endif + + +CMessagePathException::CMessagePathException(const char *a, const wchar_t *u) +{ + (*this) += a; + if (u) + { + Add_LF(); + (*this) += u; + } +} + +CMessagePathException::CMessagePathException(const wchar_t *a, const wchar_t *u) +{ + (*this) += a; + if (u) + { + Add_LF(); + (*this) += u; + } +} diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/EnumDirItems.h b/3rdparty/lzma/CPP/7zip/UI/Common/EnumDirItems.h index 7afb800a033..24f1c8bd548 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/EnumDirItems.h +++ b/3rdparty/lzma/CPP/7zip/UI/Common/EnumDirItems.h @@ -1,16 +1,12 @@ // EnumDirItems.h -#ifndef __ENUM_DIR_ITEMS_H -#define __ENUM_DIR_ITEMS_H +#ifndef ZIP7_INC_ENUM_DIR_ITEMS_H +#define ZIP7_INC_ENUM_DIR_ITEMS_H #include "../../../Common/Wildcard.h" -#include "../../../Windows/FileFind.h" - #include "DirItem.h" -void AddDirFileInfo(int phyParent, int logParent, int secureIndex, - const NWindows::NFile::NFind::CFileInfo &fi, CObjectVector<CDirItem> &dirItems); HRESULT EnumerateItems( const NWildcard::CCensor &censor, @@ -18,4 +14,25 @@ HRESULT EnumerateItems( const UString &addPathPrefix, CDirItems &dirItems); + +struct CMessagePathException: public UString +{ + CMessagePathException(const char *a, const wchar_t *u = NULL); + CMessagePathException(const wchar_t *a, const wchar_t *u = NULL); +}; + + +HRESULT EnumerateDirItemsAndSort( + NWildcard::CCensor &censor, + NWildcard::ECensorPathMode pathMode, + const UString &addPathPrefix, + UStringVector &sortedPaths, + UStringVector &sortedFullPaths, + CDirItemsStat &st, + IDirItemsCallback *callback); + +#ifdef _WIN32 +void ConvertToLongNames(NWildcard::CCensor &censor); +#endif + #endif diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/ExitCode.h b/3rdparty/lzma/CPP/7zip/UI/Common/ExitCode.h index b6d7d4dfcab..2d7b0293a0f 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/ExitCode.h +++ b/3rdparty/lzma/CPP/7zip/UI/Common/ExitCode.h @@ -1,7 +1,7 @@ // ExitCode.h -#ifndef __EXIT_CODE_H -#define __EXIT_CODE_H +#ifndef ZIP7_INC_EXIT_CODE_H +#define ZIP7_INC_EXIT_CODE_H namespace NExitCode { diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/Extract.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/Extract.cpp index 3da0aadb813..34b48719ec6 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/Extract.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Common/Extract.cpp @@ -7,10 +7,13 @@ #include "../../../Common/StringConvert.h" #include "../../../Windows/FileDir.h" +#include "../../../Windows/FileName.h" +#include "../../../Windows/ErrorMsg.h" #include "../../../Windows/PropVariant.h" #include "../../../Windows/PropVariantConv.h" #include "../Common/ExtractingFilePath.h" +#include "../Common/HashCalc.h" #include "Extract.h" #include "SetProperties.h" @@ -19,6 +22,19 @@ using namespace NWindows; using namespace NFile; using namespace NDir; + +static void SetErrorMessage(const char *message, + const FString &path, HRESULT errorCode, + UString &s) +{ + s = message; + s += " : "; + s += NError::MyFormatMessage(errorCode); + s += " : "; + s += fs2us(path); +} + + static HRESULT DecompressArchive( CCodecs *codecs, const CArchiveLink &arcLink, @@ -27,6 +43,7 @@ static HRESULT DecompressArchive( const CExtractOptions &options, bool calcCrc, IExtractCallbackUI *callback, + IFolderArchiveExtractCallback *callbackFAE, CArchiveExtractCallback *ecs, UString &errorMessage, UInt64 &stdInProcessed) @@ -47,11 +64,11 @@ static HRESULT DecompressArchive( // So it extracts different archives to one folder. // We will use top level archive name const CArc &arc0 = arcLink.Arcs[0]; - if (StringsAreEqualNoCase_Ascii(codecs->Formats[arc0.FormatIndex].Name, "pe")) + if (arc0.FormatIndex >= 0 && StringsAreEqualNoCase_Ascii(codecs->Formats[(unsigned)arc0.FormatIndex].Name, "pe")) replaceName = arc0.DefaultName; } - outDir.Replace(FSTRING_ANY_MASK, us2fs(Get_Correct_FsFile_Name(replaceName))); + outDir.Replace(FString("*"), us2fs(Get_Correct_FsFile_Name(replaceName))); bool elimIsPossible = false; UString elimPrefix; // only pure name without dir delimiter @@ -73,20 +90,25 @@ static HRESULT DecompressArchive( } } - bool allFilesAreAllowed = wildcardCensor.AreAllAllowed(); + const bool allFilesAreAllowed = wildcardCensor.AreAllAllowed(); if (!options.StdInMode) { UInt32 numItems; - RINOK(archive->GetNumberOfItems(&numItems)); + RINOK(archive->GetNumberOfItems(&numItems)) CReadArcItem item; for (UInt32 i = 0; i < numItems; i++) { - if (elimIsPossible || !allFilesAreAllowed) + if (elimIsPossible + || !allFilesAreAllowed + || options.ExcludeDirItems + || options.ExcludeFileItems) { - RINOK(arc.GetItem(i, item)); + RINOK(arc.GetItem(i, item)) + if (item.IsDir ? options.ExcludeDirItems : options.ExcludeFileItems) + continue; } else { @@ -94,7 +116,7 @@ static HRESULT DecompressArchive( item.IsAltStream = false; if (!options.NtOptions.AltStreams.Val && arc.Ask_AltStream) { - RINOK(Archive_IsItem_AltStream(arc.Archive, i, item.IsAltStream)); + RINOK(Archive_IsItem_AltStream(arc.Archive, i, item.IsAltStream)) } #endif } @@ -156,7 +178,7 @@ static HRESULT DecompressArchive( #endif if (outDir.IsEmpty()) - outDir = FTEXT(".") FSTRING_PATH_SEPARATOR; + outDir = "." STRING_PATH_SEPARATOR; /* #ifdef _WIN32 else if (NName::IsAltPathPrefix(outDir)) {} @@ -164,11 +186,8 @@ static HRESULT DecompressArchive( */ else if (!CreateComplexDir(outDir)) { - HRESULT res = ::GetLastError(); - if (res == S_OK) - res = E_FAIL; - errorMessage.SetFromAscii("Can not create output directory: "); - errorMessage += fs2us(outDir); + const HRESULT res = GetLastError_noZero_HRESULT(); + SetErrorMessage("Cannot create output directory", outDir, res, errorMessage); return res; } @@ -176,7 +195,7 @@ static HRESULT DecompressArchive( options.NtOptions, options.StdInMode ? &wildcardCensor : NULL, &arc, - callback, + callbackFAE, options.StdOutMode, options.TestMode, outDir, removePathParts, false, @@ -189,14 +208,17 @@ static HRESULT DecompressArchive( !options.TestMode && options.NtOptions.HardLinks.Val) { - RINOK(ecs->PrepareHardLinks(&realIndices)); + RINOK(ecs->PrepareHardLinks(&realIndices)) } #endif HRESULT result; - Int32 testMode = (options.TestMode && !calcCrc) ? 1: 0; + const Int32 testMode = (options.TestMode && !calcCrc) ? 1: 0; + + CArchiveExtractCallback_Closer ecsCloser(ecs); + if (options.StdInMode) { result = archive->Extract(NULL, (UInt32)(Int32)-1, testMode, ecs); @@ -206,8 +228,11 @@ static HRESULT DecompressArchive( } else result = archive->Extract(&realIndices.Front(), realIndices.Size(), testMode, ecs); - if (result == S_OK && !options.StdInMode) - result = ecs->SetDirsTimes(); + + const HRESULT res2 = ecsCloser.Close(); + if (result == S_OK) + result = res2; + return callback->ExtractResult(result); } @@ -215,17 +240,18 @@ static HRESULT DecompressArchive( Sorted list for file paths was sorted with case insensitive compare function. But FindInSorted function did binary search via case sensitive compare function */ -int Find_FileName_InSortedVector(const UStringVector &fileName, const UString &name) +int Find_FileName_InSortedVector(const UStringVector &fileNames, const UString &name); +int Find_FileName_InSortedVector(const UStringVector &fileNames, const UString &name) { - unsigned left = 0, right = fileName.Size(); + unsigned left = 0, right = fileNames.Size(); while (left != right) { - unsigned mid = (left + right) / 2; - const UString &midValue = fileName[mid]; - int compare = CompareFileNames(name, midValue); - if (compare == 0) - return mid; - if (compare < 0) + const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); + const UString &midVal = fileNames[mid]; + const int comp = CompareFileNames(name, midVal); + if (comp == 0) + return (int)mid; + if (comp < 0) right = mid; else left = mid + 1; @@ -233,7 +259,10 @@ int Find_FileName_InSortedVector(const UStringVector &fileName, const UString &n return -1; } + + HRESULT Extract( + // DECL_EXTERNAL_CODECS_LOC_VARS CCodecs *codecs, const CObjectVector<COpenType> &types, const CIntVector &excludedFormats, @@ -242,7 +271,8 @@ HRESULT Extract( const CExtractOptions &options, IOpenCallbackUI *openCallback, IExtractCallbackUI *extractCallback, - #ifndef _SFX + IFolderArchiveExtractCallback *faeCallback, + #ifndef Z7_SFX IHashCalc *hash, #endif UString &errorMessage, @@ -262,11 +292,19 @@ HRESULT Extract( fi.Size = 0; if (!options.StdInMode) { - const FString &arcPath = us2fs(arcPaths[i]); - if (!fi.Find(arcPath)) - throw "there is no such archive"; + const FString arcPath = us2fs(arcPaths[i]); + if (!fi.Find_FollowLink(arcPath)) + { + const HRESULT errorCode = GetLastError_noZero_HRESULT(); + SetErrorMessage("Cannot find archive file", arcPath, errorCode, errorMessage); + return errorCode; + } if (fi.IsDir()) - throw "can't decompress folder"; + { + HRESULT errorCode = E_FAIL; + SetErrorMessage("The item is a directory", arcPath, errorCode, errorMessage); + return errorCode; + } } arcSizes.Add(fi.Size); totalPackSize += fi.Size; @@ -278,15 +316,22 @@ HRESULT Extract( CArchiveExtractCallback *ecs = new CArchiveExtractCallback; CMyComPtr<IArchiveExtractCallback> ec(ecs); - bool multi = (numArcs > 1); - ecs->InitForMulti(multi, options.PathMode, options.OverwriteMode); - #ifndef _SFX + + const bool multi = (numArcs > 1); + + ecs->InitForMulti(multi, + options.PathMode, + options.OverwriteMode, + options.ZoneMode, + false // keepEmptyDirParts + ); + #ifndef Z7_SFX ecs->SetHashMethods(hash); #endif if (multi) { - RINOK(extractCallback->SetTotal(totalPackSize)); + RINOK(faeCallback->SetTotal(totalPackSize)) } UInt64 totalPackProcessed = 0; @@ -297,31 +342,41 @@ HRESULT Extract( if (skipArcs[i]) continue; + ecs->InitBeforeNewArchive(); + const UString &arcPath = arcPaths[i]; NFind::CFileInfo fi; if (options.StdInMode) { - fi.Size = 0; - fi.Attrib = 0; + // do we need ctime and mtime? + fi.ClearBase(); + fi.Size = 0; // (UInt64)(Int64)-1; + fi.SetAsFile(); + // NTime::GetCurUtc_FiTime(fi.MTime); + // fi.CTime = fi.ATime = fi.MTime; } else { - if (!fi.Find(us2fs(arcPath)) || fi.IsDir()) - throw "there is no such archive"; + if (!fi.Find_FollowLink(us2fs(arcPath)) || fi.IsDir()) + { + const HRESULT errorCode = GetLastError_noZero_HRESULT(); + SetErrorMessage("Cannot find archive file", us2fs(arcPath), errorCode, errorMessage); + return errorCode; + } } /* - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO openCallback->Open_Clear_PasswordWasAsked_Flag(); #endif */ - RINOK(extractCallback->BeforeOpen(arcPath, options.TestMode)); + RINOK(extractCallback->BeforeOpen(arcPath, options.TestMode)) CArchiveLink arcLink; CObjectVector<COpenType> types2 = types; /* - #ifndef _SFX + #ifndef Z7_SFX if (types.IsEmpty()) { int pos = arcPath.ReverseFind(L'.'); @@ -349,7 +404,7 @@ HRESULT Extract( */ COpenOptions op; - #ifndef _SFX + #ifndef Z7_SFX op.props = &options.Properties; #endif op.codecs = codecs; @@ -365,19 +420,54 @@ HRESULT Extract( return result; // arcLink.Set_ErrorsText(); - RINOK(extractCallback->OpenResult(codecs, arcLink, arcPath, result)); + RINOK(extractCallback->OpenResult(codecs, arcLink, arcPath, result)) if (result != S_OK) { thereAreNotOpenArcs = true; if (!options.StdInMode) + totalPackProcessed += fi.Size; + continue; + } + + #if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX) + if (options.ZoneMode != NExtract::NZoneIdMode::kNone + && !options.StdInMode) + { + ReadZoneFile_Of_BaseFile(us2fs(arcPath), ecs->ZoneBuf); + } + #endif + + + if (arcLink.Arcs.Size() != 0) + { + if (arcLink.GetArc()->IsHashHandler(op)) { - NFind::CFileInfo fi2; - if (fi2.Find(us2fs(arcPath))) - if (!fi2.IsDir()) - totalPackProcessed += fi2.Size; + if (!options.TestMode) + { + /* real Extracting to files is possible. + But user can think that hash archive contains real files. + So we block extracting here. */ + // v23.00 : we don't break process. + RINOK(extractCallback->OpenResult(codecs, arcLink, arcPath, E_NOTIMPL)) + thereAreNotOpenArcs = true; + if (!options.StdInMode) + totalPackProcessed += fi.Size; + continue; + // return E_NOTIMPL; // before v23 + } + FString dirPrefix = us2fs(options.HashDir); + if (dirPrefix.IsEmpty()) + { + if (!NFile::NDir::GetOnlyDirPrefix(us2fs(arcPath), dirPrefix)) + { + // return GetLastError_noZero_HRESULT(); + } + } + if (!dirPrefix.IsEmpty()) + NName::NormalizeDirPathPrefix(dirPrefix); + ecs->DirPathPrefix_for_HashFiles = dirPrefix; } - continue; } if (!options.StdInMode) @@ -389,7 +479,7 @@ HRESULT Extract( // numArcs = arcPaths.Size(); if (arcLink.VolumePaths.Size() != 0) { - Int64 correctionSize = arcLink.VolumesSize; + Int64 correctionSize = (Int64)arcLink.VolumesSize; FOR_VECTOR (v, arcLink.VolumePaths) { int index = Find_FileName_InSortedVector(arcPathsFull, arcLink.VolumePaths[v]); @@ -407,8 +497,8 @@ HRESULT Extract( Int64 newPackSize = (Int64)totalPackSize + correctionSize; if (newPackSize < 0) newPackSize = 0; - totalPackSize = newPackSize; - RINOK(extractCallback->SetTotal(totalPackSize)); + totalPackSize = (UInt64)newPackSize; + RINOK(faeCallback->SetTotal(totalPackSize)) } } } @@ -416,24 +506,29 @@ HRESULT Extract( /* // Now openCallback and extractCallback use same object. So we don't need to send password. - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO bool passwordIsDefined; UString password; - RINOK(openCallback->Open_GetPasswordIfAny(passwordIsDefined, password)); + RINOK(openCallback->Open_GetPasswordIfAny(passwordIsDefined, password)) if (passwordIsDefined) { - RINOK(extractCallback->SetPassword(password)); + RINOK(extractCallback->SetPassword(password)) } #endif */ CArc &arc = arcLink.Arcs.Back(); - arc.MTimeDefined = (!options.StdInMode && !fi.IsDevice); - arc.MTime = fi.MTime; + arc.MTime.Def = !options.StdInMode + #ifdef _WIN32 + && !fi.IsDevice + #endif + ; + if (arc.MTime.Def) + arc.MTime.Set_From_FiTime(fi.MTime); UInt64 packProcessed; - bool calcCrc = - #ifndef _SFX + const bool calcCrc = + #ifndef Z7_SFX (hash != NULL); #else false; @@ -446,7 +541,8 @@ HRESULT Extract( wildcardCensor, options, calcCrc, - extractCallback, ecs, errorMessage, packProcessed)); + extractCallback, faeCallback, ecs, + errorMessage, packProcessed)) if (!options.StdInMode) packProcessed = fi.Size + arcLink.VolumesSize; @@ -459,8 +555,8 @@ HRESULT Extract( if (multi || thereAreNotOpenArcs) { - RINOK(extractCallback->SetTotal(totalPackSize)); - RINOK(extractCallback->SetCompleted(&totalPackProcessed)); + RINOK(faeCallback->SetTotal(totalPackSize)) + RINOK(faeCallback->SetCompleted(&totalPackProcessed)) } st.NumFolders = ecs->NumFolders; diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/Extract.h b/3rdparty/lzma/CPP/7zip/UI/Common/Extract.h index 03ac74b2d0b..b20f607d6d9 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/Extract.h +++ b/3rdparty/lzma/CPP/7zip/UI/Common/Extract.h @@ -1,7 +1,7 @@ // Extract.h -#ifndef __EXTRACT_H -#define __EXTRACT_H +#ifndef ZIP7_INC_EXTRACT_H +#define ZIP7_INC_EXTRACT_H #include "../../../Windows/FileFind.h" @@ -17,20 +17,28 @@ struct CExtractOptionsBase { CBoolPair ElimDup; - + + bool ExcludeDirItems; + bool ExcludeFileItems; + bool PathMode_Force; bool OverwriteMode_Force; NExtract::NPathMode::EEnum PathMode; NExtract::NOverwriteMode::EEnum OverwriteMode; + NExtract::NZoneIdMode::EEnum ZoneMode; FString OutputDir; CExtractNtOptions NtOptions; + UString HashDir; CExtractOptionsBase(): + ExcludeDirItems(false), + ExcludeFileItems(false), PathMode_Force(false), OverwriteMode_Force(false), PathMode(NExtract::NPathMode::kFullPaths), - OverwriteMode(NExtract::NOverwriteMode::kAsk) + OverwriteMode(NExtract::NOverwriteMode::kAsk), + ZoneMode(NExtract::NZoneIdMode::kNone) {} }; @@ -44,19 +52,21 @@ struct CExtractOptions: public CExtractOptionsBase // bool ShowDialog; // bool PasswordEnabled; // UString Password; - #ifndef _SFX + #ifndef Z7_SFX CObjectVector<CProperty> Properties; #endif - #ifdef EXTERNAL_CODECS + /* + #ifdef Z7_EXTERNAL_CODECS CCodecs *Codecs; #endif + */ CExtractOptions(): - TestMode(false), StdInMode(false), StdOutMode(false), - YesToAll(false) + YesToAll(false), + TestMode(false) {} }; @@ -77,6 +87,7 @@ struct CDecompressStat }; HRESULT Extract( + // DECL_EXTERNAL_CODECS_LOC_VARS CCodecs *codecs, const CObjectVector<COpenType> &types, const CIntVector &excludedFormats, @@ -85,7 +96,8 @@ HRESULT Extract( const CExtractOptions &options, IOpenCallbackUI *openCallback, IExtractCallbackUI *extractCallback, - #ifndef _SFX + IFolderArchiveExtractCallback *faeCallback, + #ifndef Z7_SFX IHashCalc *hash, #endif UString &errorMessage, diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/ExtractMode.h b/3rdparty/lzma/CPP/7zip/UI/Common/ExtractMode.h index 3b2b9a02e81..6e38f2601fb 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/ExtractMode.h +++ b/3rdparty/lzma/CPP/7zip/UI/Common/ExtractMode.h @@ -1,7 +1,7 @@ // ExtractMode.h -#ifndef __EXTRACT_MODE_H -#define __EXTRACT_MODE_H +#ifndef ZIP7_INC_EXTRACT_MODE_H +#define ZIP7_INC_EXTRACT_MODE_H namespace NExtract { @@ -29,6 +29,16 @@ namespace NOverwriteMode }; } +namespace NZoneIdMode +{ + enum EEnum + { + kNone, + kAll, + kOffice + }; +} + } #endif diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/ExtractingFilePath.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/ExtractingFilePath.cpp index 39e67b7f2ed..88da4ad36c0 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/ExtractingFilePath.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Common/ExtractingFilePath.cpp @@ -8,6 +8,18 @@ #include "ExtractingFilePath.h" +extern +bool g_PathTrailReplaceMode; +bool g_PathTrailReplaceMode = + #ifdef _WIN32 + true + #else + false + #endif + ; + + +#ifdef _WIN32 static void ReplaceIncorrectChars(UString &s) { { @@ -22,24 +34,60 @@ static void ReplaceIncorrectChars(UString &s) || #endif c == WCHAR_PATH_SEPARATOR) - s.ReplaceOneCharAtPos(i, '_'); + { + #if WCHAR_PATH_SEPARATOR != L'/' + // 22.00 : WSL replacement for backslash + if (c == WCHAR_PATH_SEPARATOR) + c = WCHAR_IN_FILE_NAME_BACKSLASH_REPLACEMENT; + else + #endif + c = '_'; + s.ReplaceOneCharAtPos(i, + c + // (wchar_t)(0xf000 + c) // 21.02 debug: WSL encoding for unsupported characters + ); + } } } - #ifdef _WIN32 + if (g_PathTrailReplaceMode) { - for (unsigned i = s.Len(); i != 0;) + /* + // if (g_PathTrailReplaceMode == 1) { - wchar_t c = s[--i]; - if (c != '.' && c != ' ') - break; - s.ReplaceOneCharAtPos(i, '_'); + if (!s.IsEmpty()) + { + wchar_t c = s.Back(); + if (c == '.' || c == ' ') + { + // s += (wchar_t)(0x9c); // STRING TERMINATOR + s += (wchar_t)'_'; + } + } + } + else + */ + { + unsigned i; + for (i = s.Len(); i != 0;) + { + wchar_t c = s[i - 1]; + if (c != '.' && c != ' ') + break; + i--; + s.ReplaceOneCharAtPos(i, '_'); + // s.ReplaceOneCharAtPos(i, (c == ' ' ? (wchar_t)(0x2423) : (wchar_t)0x00B7)); + } + /* + if (g_PathTrailReplaceMode > 1 && i != s.Len()) + { + s.DeleteFrom(i); + } + */ } } - #endif } - -#ifdef _WIN32 +#endif /* WinXP-64 doesn't support ':', '\\' and '/' symbols in name of alt stream. But colon in postfix ":$DATA" is allowed. @@ -61,9 +109,11 @@ void Correct_AltStream_Name(UString &s) s.ReplaceOneCharAtPos(i, '_'); } if (s.IsEmpty()) - s = L'_'; + s = '_'; } +#ifdef _WIN32 + static const unsigned g_ReservedWithNum_Index = 4; static const char * const g_ReservedNames[] = @@ -74,7 +124,7 @@ static const char * const g_ReservedNames[] = static bool IsSupportedName(const UString &name) { - for (unsigned i = 0; i < ARRAY_SIZE(g_ReservedNames); i++) + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_ReservedNames); i++) { const char *reservedName = g_ReservedNames[i]; unsigned len = MyStringLen(reservedName); @@ -112,7 +162,10 @@ static void CorrectUnsupportedName(UString &name) static void Correct_PathPart(UString &s) { // "." and ".." - if (s[0] == '.' && (s[1] == 0 || s[1] == '.' && s[2] == 0)) + if (s.IsEmpty()) + return; + + if (s[0] == '.' && (s[1] == 0 || (s[1] == '.' && s[2] == 0))) s.Empty(); #ifdef _WIN32 else @@ -120,8 +173,8 @@ static void Correct_PathPart(UString &s) #endif } -// static const wchar_t *k_EmptyReplaceName = L"[]"; -static const wchar_t k_EmptyReplaceName = L'_'; +// static const char * const k_EmptyReplaceName = "[]"; +static const char k_EmptyReplaceName = '_'; UString Get_Correct_FsFile_Name(const UString &name) { @@ -138,7 +191,7 @@ UString Get_Correct_FsFile_Name(const UString &name) } -void Correct_FsPath(bool absIsAllowed, UStringVector &parts, bool isDir) +void Correct_FsPath(bool absIsAllowed, bool keepAndReplaceEmptyPrefixes, UStringVector &parts, bool isDir) { unsigned i = 0; @@ -147,6 +200,7 @@ void Correct_FsPath(bool absIsAllowed, UStringVector &parts, bool isDir) #if defined(_WIN32) && !defined(UNDER_CE) bool isDrive = false; #endif + if (parts[0].IsEmpty()) { i = 1; @@ -157,7 +211,7 @@ void Correct_FsPath(bool absIsAllowed, UStringVector &parts, bool isDir) if (parts.Size() > 2 && parts[2] == L"?") { i = 3; - if (parts.Size() > 3 && NWindows::NFile::NName::IsDrivePath2(parts[3])) + if (parts.Size() > 3 && NWindows::NFile::NName::IsDrivePath2(parts[3])) { isDrive = true; i = 4; @@ -176,16 +230,19 @@ void Correct_FsPath(bool absIsAllowed, UStringVector &parts, bool isDir) if (isDrive) { // we convert "c:name" to "c:\name", if absIsAllowed path. - const UString &ds = parts[i - 1]; - if (ds.Len() != 2) + UString &ds = parts[i - 1]; + if (ds.Len() > 2) { - UString s = ds.Ptr(2); - parts.Insert(i, s); + parts.Insert(i, ds.Ptr(2)); + ds.DeleteFrom(2); } } #endif } + if (i != 0) + keepAndReplaceEmptyPrefixes = false; + for (; i < parts.Size();) { UString &s = parts[i]; @@ -194,15 +251,17 @@ void Correct_FsPath(bool absIsAllowed, UStringVector &parts, bool isDir) if (s.IsEmpty()) { - if (isDir || i != parts.Size() - 1) - { - parts.Delete(i); - continue; - } + if (!keepAndReplaceEmptyPrefixes) + if (isDir || i != parts.Size() - 1) + { + parts.Delete(i); + continue; + } s = k_EmptyReplaceName; } else { + keepAndReplaceEmptyPrefixes = false; #ifdef _WIN32 CorrectUnsupportedName(s); #endif @@ -214,7 +273,7 @@ void Correct_FsPath(bool absIsAllowed, UStringVector &parts, bool isDir) if (!isDir) { if (parts.IsEmpty()) - parts.Add(k_EmptyReplaceName); + parts.Add((UString)k_EmptyReplaceName); else { UString &s = parts.Back(); diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/ExtractingFilePath.h b/3rdparty/lzma/CPP/7zip/UI/Common/ExtractingFilePath.h index a52a1f4a5b4..bb1732fc8bb 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/ExtractingFilePath.h +++ b/3rdparty/lzma/CPP/7zip/UI/Common/ExtractingFilePath.h @@ -1,18 +1,30 @@ // ExtractingFilePath.h -#ifndef __EXTRACTING_FILE_PATH_H -#define __EXTRACTING_FILE_PATH_H +#ifndef ZIP7_INC_EXTRACTING_FILE_PATH_H +#define ZIP7_INC_EXTRACTING_FILE_PATH_H #include "../../../Common/MyString.h" -#ifdef _WIN32 +// #ifdef _WIN32 void Correct_AltStream_Name(UString &s); -#endif +// #endif // replaces unsuported characters, and replaces "." , ".." and "" to "[]" UString Get_Correct_FsFile_Name(const UString &name); -void Correct_FsPath(bool absIsAllowed, UStringVector &parts, bool isDir); +/* + Correct_FsPath() corrects path parts to prepare it for File System operations. + It also corrects empty path parts like "\\\\": + - frontal empty path parts : it removes them or changes them to "_" + - another empty path parts : it removes them + if (absIsAllowed && path is absolute) : it removes empty path parts after start absolute path prefix marker + else + { + if (!keepAndReplaceEmptyPrefixes) : it removes empty path parts + if ( keepAndReplaceEmptyPrefixes) : it changes each empty frontal path part to "_" + } +*/ +void Correct_FsPath(bool absIsAllowed, bool keepAndReplaceEmptyPrefixes, UStringVector &parts, bool isDir); UString MakePathFromParts(const UStringVector &parts); diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/HashCalc.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/HashCalc.cpp index 60a747d5590..94c8a06fc8b 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/HashCalc.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Common/HashCalc.cpp @@ -3,44 +3,52 @@ #include "StdAfx.h" #include "../../../../C/Alloc.h" +#include "../../../../C/CpuArch.h" +#include "../../../Common/DynLimBuf.h" +#include "../../../Common/IntToString.h" #include "../../../Common/StringToInt.h" #include "../../Common/FileStreams.h" +#include "../../Common/ProgressUtils.h" +#include "../../Common/StreamObjects.h" #include "../../Common/StreamUtils.h" +#include "../../Archive/Common/ItemNameUtils.h" +#include "../../Archive/IArchive.h" + #include "EnumDirItems.h" #include "HashCalc.h" using namespace NWindows; +#ifdef Z7_EXTERNAL_CODECS +extern const CExternalCodecs *g_ExternalCodecs_Ptr; +#endif + class CHashMidBuf { void *_data; public: - CHashMidBuf(): _data(0) {} + CHashMidBuf(): _data(NULL) {} operator void *() { return _data; } bool Alloc(size_t size) { - if (_data != 0) + if (_data) return false; _data = ::MidAlloc(size); - return _data != 0; + return _data != NULL; } ~CHashMidBuf() { ::MidFree(_data); } }; -static const char *k_DefaultHashMethod = "CRC32"; +static const char * const k_DefaultHashMethod = "CRC32"; HRESULT CHashBundle::SetMethods(DECL_EXTERNAL_CODECS_LOC_VARS const UStringVector &hashMethods) { UStringVector names = hashMethods; if (names.IsEmpty()) - { - UString s; - s.SetFromAscii(k_DefaultHashMethod); - names.Add(s); - } + names.Add(UString(k_DefaultHashMethod)); CRecordVector<CMethodId> ids; CObjectVector<COneMethodInfo> methods; @@ -49,7 +57,7 @@ HRESULT CHashBundle::SetMethods(DECL_EXTERNAL_CODECS_LOC_VARS const UStringVecto for (i = 0; i < names.Size(); i++) { COneMethodInfo m; - RINOK(m.ParseMethodFromString(names[i])); + RINOK(m.ParseMethodFromString(names[i])) if (m.MethodName.IsEmpty()) m.MethodName = k_DefaultHashMethod; @@ -84,7 +92,7 @@ HRESULT CHashBundle::SetMethods(DECL_EXTERNAL_CODECS_LOC_VARS const UStringVecto { CMyComPtr<IHasher> hasher; AString name; - RINOK(CreateHasher(EXTERNAL_CODECS_LOC_VARS ids[i], name, hasher)); + RINOK(CreateHasher(EXTERNAL_CODECS_LOC_VARS ids[i], name, hasher)) if (!hasher) throw "Can't create hasher"; const COneMethodInfo &m = methods[i]; @@ -92,17 +100,17 @@ HRESULT CHashBundle::SetMethods(DECL_EXTERNAL_CODECS_LOC_VARS const UStringVecto CMyComPtr<ICompressSetCoderProperties> scp; hasher.QueryInterface(IID_ICompressSetCoderProperties, &scp); if (scp) - RINOK(m.SetCoderProps(scp, NULL)); + RINOK(m.SetCoderProps(scp, NULL)) } - UInt32 digestSize = hasher->GetDigestSize(); + const UInt32 digestSize = hasher->GetDigestSize(); if (digestSize > k_HashCalc_DigestSize_Max) return E_NOTIMPL; CHasherState &h = Hashers.AddNew(); + h.DigestSize = digestSize; h.Hasher = hasher; h.Name = name; - h.DigestSize = digestSize; for (unsigned k = 0; k < k_HashCalc_NumGroups; k++) - memset(h.Digests[k], 0, digestSize); + h.InitDigestGroup(k); } return S_OK; @@ -115,7 +123,7 @@ void CHashBundle::InitForNewFile() { CHasherState &h = Hashers[i]; h.Hasher->Init(); - memset(h.Digests[k_HashCalc_Index_Current], 0, h.DigestSize); + h.InitDigestGroup(k_HashCalc_Index_Current); } } @@ -134,14 +142,46 @@ void CHashBundle::SetSize(UInt64 size) static void AddDigests(Byte *dest, const Byte *src, UInt32 size) { unsigned next = 0; - for (UInt32 i = 0; i < size; i++) + /* + // we could use big-endian addition for sha-1 and sha-256 + // but another hashers are little-endian + if (size > 8) + { + for (unsigned i = size; i != 0;) + { + i--; + next += (unsigned)dest[i] + (unsigned)src[i]; + dest[i] = (Byte)next; + next >>= 8; + } + } + else + */ { - next += (unsigned)dest[i] + (unsigned)src[i]; + for (unsigned i = 0; i < size; i++) + { + next += (unsigned)dest[i] + (unsigned)src[i]; + dest[i] = (Byte)next; + next >>= 8; + } + } + + // we use little-endian to store extra bytes + dest += k_HashCalc_DigestSize_Max; + for (unsigned i = 0; i < k_HashCalc_ExtraSize; i++) + { + next += (unsigned)dest[i]; dest[i] = (Byte)next; next >>= 8; } } +void CHasherState::AddDigest(unsigned groupIndex, const Byte *data) +{ + NumSums[groupIndex]++; + AddDigests(Digests[groupIndex], data, DigestSize); +} + void CHashBundle::Final(bool isDir, bool isAltStream, const UString &path) { if (isDir) @@ -167,9 +207,9 @@ void CHashBundle::Final(bool isDir, bool isAltStream, const UString &path) CHasherState &h = Hashers[i]; if (!isDir) { - h.Hasher->Final(h.Digests[0]); + h.Hasher->Final(h.Digests[0]); // k_HashCalc_Index_Current if (!isAltStream) - AddDigests(h.Digests[k_HashCalc_Index_DataSum], h.Digests[0], h.DigestSize); + h.AddDigest(k_HashCalc_Index_DataSum, h.Digests[0]); } h.Hasher->Init(); @@ -179,6 +219,15 @@ void CHashBundle::Final(bool isDir, bool isAltStream, const UString &path) for (unsigned k = 0; k < path.Len(); k++) { wchar_t c = path[k]; + + // 21.04: we want same hash for linux and windows paths + #if CHAR_PATH_SEPARATOR != '/' + if (c == CHAR_PATH_SEPARATOR) + c = '/'; + // if (c == (wchar_t)('\\' + 0xf000)) c = '\\'; // to debug WSL + // if (c > 0xf000 && c < 0xf080) c -= 0xf000; // to debug WSL + #endif + Byte temp[2] = { (Byte)(c & 0xFF), (Byte)((c >> 8) & 0xFF) }; h.Hasher->Update(temp, 2); } @@ -186,9 +235,216 @@ void CHashBundle::Final(bool isDir, bool isAltStream, const UString &path) Byte tempDigest[k_HashCalc_DigestSize_Max]; h.Hasher->Final(tempDigest); if (!isAltStream) - AddDigests(h.Digests[k_HashCalc_Index_NamesSum], tempDigest, h.DigestSize); - AddDigests(h.Digests[k_HashCalc_Index_StreamsSum], tempDigest, h.DigestSize); + h.AddDigest(k_HashCalc_Index_NamesSum, tempDigest); + h.AddDigest(k_HashCalc_Index_StreamsSum, tempDigest); + } +} + + +static void CSum_Name_OriginalToEscape(const AString &src, AString &dest) +{ + dest.Empty(); + for (unsigned i = 0; i < src.Len();) + { + char c = src[i++]; + if (c == '\n') + { + dest += '\\'; + c = 'n'; + } + else if (c == '\\') + dest += '\\'; + dest += c; + } +} + + +static bool CSum_Name_EscapeToOriginal(const char *s, AString &dest) +{ + bool isOK = true; + dest.Empty(); + for (;;) + { + char c = *s++; + if (c == 0) + break; + if (c == '\\') + { + const char c1 = *s; + if (c1 == 'n') + { + c = '\n'; + s++; + } + else if (c1 == '\\') + { + c = c1; + s++; + } + else + { + // original md5sum returns NULL for such bad strings + isOK = false; + } + } + dest += c; + } + return isOK; +} + + + +static void SetSpacesAndNul(char *s, unsigned num) +{ + for (unsigned i = 0; i < num; i++) + s[i] = ' '; + s[num] = 0; +} + +static const unsigned kHashColumnWidth_Min = 4 * 2; + +static unsigned GetColumnWidth(unsigned digestSize) +{ + const unsigned width = digestSize * 2; + return width < kHashColumnWidth_Min ? kHashColumnWidth_Min: width; +} + + +static void AddHashResultLine( + AString &_s, + // bool showHash, + // UInt64 fileSize, bool showSize, + const CObjectVector<CHasherState> &hashers + // unsigned digestIndex, = k_HashCalc_Index_Current + ) +{ + FOR_VECTOR (i, hashers) + { + const CHasherState &h = hashers[i]; + char s[k_HashCalc_DigestSize_Max * 2 + 64]; + s[0] = 0; + // if (showHash) + HashHexToString(s, h.Digests[k_HashCalc_Index_Current], h.DigestSize); + const unsigned pos = (unsigned)strlen(s); + const int numSpaces = (int)GetColumnWidth(h.DigestSize) - (int)pos; + if (numSpaces > 0) + SetSpacesAndNul(s + pos, (unsigned)numSpaces); + if (i != 0) + _s.Add_Space(); + _s += s; + } + + /* + if (showSize) + { + _s.Add_Space(); + static const unsigned kSizeField_Len = 13; // same as in HashCon.cpp + char s[kSizeField_Len + 32]; + char *p = s; + SetSpacesAndNul(s, kSizeField_Len); + p = s + kSizeField_Len; + ConvertUInt64ToString(fileSize, p); + int numSpaces = (int)kSizeField_Len - (int)strlen(p); + if (numSpaces > 0) + p -= (unsigned)numSpaces; + _s += p; + } + */ +} + + +static void Add_LF(CDynLimBuf &hashFileString, const CHashOptionsLocal &options) +{ + hashFileString += (char)(options.HashMode_Zero.Val ? 0 : '\n'); +} + + + + +static void WriteLine(CDynLimBuf &hashFileString, + const CHashOptionsLocal &options, + const UString &path2, + bool isDir, + const AString &methodName, + const AString &hashesString) +{ + if (options.HashMode_OnlyHash.Val) + { + hashFileString += hashesString; + Add_LF(hashFileString, options); + return; + } + + UString path = path2; + + bool isBin = false; + const bool zeroMode = options.HashMode_Zero.Val; + const bool tagMode = options.HashMode_Tag.Val; + +#if CHAR_PATH_SEPARATOR != '/' + path.Replace(WCHAR_PATH_SEPARATOR, L'/'); + // path.Replace((wchar_t)('\\' + 0xf000), L'\\'); // to debug WSL +#endif + + AString utf8; + ConvertUnicodeToUTF8(path, utf8); + + AString esc; + CSum_Name_OriginalToEscape(utf8, esc); + + if (!zeroMode) + { + if (esc != utf8) + { + /* Original md5sum writes escape in that case. + We do same for compatibility with original md5sum. */ + hashFileString += '\\'; + } + } + + if (isDir && !esc.IsEmpty() && esc.Back() != '/') + esc += '/'; + + if (tagMode) + { + if (!methodName.IsEmpty()) + { + hashFileString += methodName; + hashFileString += ' '; + } + hashFileString += '('; + hashFileString += esc; + hashFileString += ')'; + hashFileString += " = "; } + + hashFileString += hashesString; + + if (!tagMode) + { + hashFileString += ' '; + hashFileString += (char)(isBin ? '*' : ' '); + hashFileString += esc; + } + + Add_LF(hashFileString, options); +} + + + +static void WriteLine(CDynLimBuf &hashFileString, + const CHashOptionsLocal &options, + const UString &path, + bool isDir, + const CHashBundle &hb) +{ + AString methodName; + if (!hb.Hashers.IsEmpty()) + methodName = hb.Hashers[0].Name; + + AString hashesString; + AddHashResultLine(hashesString, hb.Hashers); + WriteLine(hashFileString, options, path, isDir, methodName, hashesString); } @@ -206,16 +462,19 @@ HRESULT HashCalc( { CDirItem di; di.Size = (UInt64)(Int64)-1; - di.Attrib = 0; - di.MTime.dwLowDateTime = 0; - di.MTime.dwHighDateTime = 0; - di.CTime = di.ATime = di.MTime; + di.SetAsFile(); dirItems.Items.Add(di); } else { - RINOK(callback->StartScanning()); + RINOK(callback->StartScanning()) + + dirItems.SymLinks = options.SymLinks.Val; dirItems.ScanAltStreams = options.AltStreamsMode; + dirItems.ExcludeDirItems = censor.ExcludeDirItems; + dirItems.ExcludeFileItems = censor.ExcludeFileItems; + + dirItems.ShareForWrite = options.OpenShareForWrite; HRESULT res = EnumerateItems(censor, options.PathMode, @@ -228,23 +487,25 @@ HRESULT HashCalc( errorInfo = "Scanning error"; return res; } - RINOK(callback->FinishScanning(dirItems.Stat)); + RINOK(callback->FinishScanning(dirItems.Stat)) } unsigned i; CHashBundle hb; - RINOK(hb.SetMethods(EXTERNAL_CODECS_LOC_VARS options.Methods)); - hb.Init(); + RINOK(hb.SetMethods(EXTERNAL_CODECS_LOC_VARS options.Methods)) + // hb.Init(); hb.NumErrors = dirItems.Stat.NumErrors; - + + UInt64 totalSize = 0; if (options.StdInMode) { - RINOK(callback->SetNumFiles(1)); + RINOK(callback->SetNumFiles(1)) } else { - RINOK(callback->SetTotal(dirItems.Stat.GetTotalBytes())); + totalSize = dirItems.Stat.GetTotalBytes(); + RINOK(callback->SetTotal(totalSize)) } const UInt32 kBufSize = 1 << 15; @@ -254,7 +515,12 @@ HRESULT HashCalc( UInt64 completeValue = 0; - RINOK(callback->BeforeFirstFile(hb)); + RINOK(callback->BeforeFirstFile(hb)) + + /* + CDynLimBuf hashFileString((size_t)1 << 31); + const bool needGenerate = !options.HashFilePath.IsEmpty(); + */ for (i = 0; i < dirItems.Items.Size(); i++) { @@ -262,43 +528,79 @@ HRESULT HashCalc( UString path; bool isDir = false; bool isAltStream = false; + if (options.StdInMode) { inStream = new CStdInFileStream; } else { - CInFileStream *inStreamSpec = new CInFileStream; - inStream = inStreamSpec; - const CDirItem &dirItem = dirItems.Items[i]; - isDir = dirItem.IsDir(); - isAltStream = dirItem.IsAltStream; path = dirItems.GetLogPath(i); - if (!isDir) + const CDirItem &di = dirItems.Items[i]; + #ifdef _WIN32 + isAltStream = di.IsAltStream; + #endif + + #ifndef UNDER_CE + // if (di.AreReparseData()) + if (di.ReparseData.Size() != 0) + { + CBufInStream *inStreamSpec = new CBufInStream(); + inStream = inStreamSpec; + inStreamSpec->Init(di.ReparseData, di.ReparseData.Size()); + } + else + #endif { - FString phyPath = dirItems.GetPhyPath(i); - if (!inStreamSpec->OpenShared(phyPath, options.OpenShareForWrite)) + CInFileStream *inStreamSpec = new CInFileStream; + inStreamSpec->Set_PreserveATime(options.PreserveATime); + inStream = inStreamSpec; + isDir = di.IsDir(); + if (!isDir) { - HRESULT res = callback->OpenFileError(phyPath, ::GetLastError()); - hb.NumErrors++; - if (res != S_FALSE) - return res; - continue; + const FString phyPath = dirItems.GetPhyPath(i); + if (!inStreamSpec->OpenShared(phyPath, options.OpenShareForWrite)) + { + HRESULT res = callback->OpenFileError(phyPath, ::GetLastError()); + hb.NumErrors++; + if (res != S_FALSE) + return res; + continue; + } + if (!options.StdInMode) + { + UInt64 curSize = 0; + if (inStreamSpec->GetSize(&curSize) == S_OK) + { + if (curSize > di.Size) + { + totalSize += curSize - di.Size; + RINOK(callback->SetTotal(totalSize)) + // printf("\ntotal = %d MiB\n", (unsigned)(totalSize >> 20)); + } + } + } + // inStreamSpec->ReloadProps(); } } } - RINOK(callback->GetStream(path, isDir)); + + RINOK(callback->GetStream(path, isDir)) UInt64 fileSize = 0; hb.InitForNewFile(); + if (!isDir) { for (UInt32 step = 0;; step++) { if ((step & 0xFF) == 0) - RINOK(callback->SetCompleted(&completeValue)); + { + // printf("\ncompl = %d\n", (unsigned)(completeValue >> 20)); + RINOK(callback->SetCompleted(&completeValue)) + } UInt32 size; - RINOK(inStream->Read(buf, kBufSize, &size)); + RINOK(inStream->Read(buf, kBufSize, &size)) if (size == 0) break; hb.Update(buf, size); @@ -306,20 +608,54 @@ HRESULT HashCalc( completeValue += size; } } + hb.Final(isDir, isAltStream, path); - RINOK(callback->SetOperationResult(fileSize, hb, !isDir)); - RINOK(callback->SetCompleted(&completeValue)); + + /* + if (needGenerate + && (options.HashMode_Dirs.Val || !isDir)) + { + WriteLine(hashFileString, + options, + path, // change it + isDir, + hb); + + if (hashFileString.IsError()) + return E_OUTOFMEMORY; + } + */ + + RINOK(callback->SetOperationResult(fileSize, hb, !isDir)) + RINOK(callback->SetCompleted(&completeValue)) + } + + /* + if (needGenerate) + { + NFile::NIO::COutFile file; + if (!file.Create(us2fs(options.HashFilePath), true)) // createAlways + return GetLastError_noZero_HRESULT(); + if (!file.WriteFull(hashFileString, hashFileString.Len())) + return GetLastError_noZero_HRESULT(); } + */ + return callback->AfterLastFile(hb); } -static inline char GetHex(unsigned v) +static inline char GetHex_Upper(unsigned v) { return (char)((v < 10) ? ('0' + v) : ('A' + (v - 10))); } -void AddHashHexToString(char *dest, const Byte *data, UInt32 size) +static inline char GetHex_Lower(unsigned v) +{ + return (char)((v < 10) ? ('0' + v) : ('a' + (v - 10))); +} + +void HashHexToString(char *dest, const Byte *data, UInt32 size) { dest[size * 2] = 0; @@ -334,18 +670,1441 @@ void AddHashHexToString(char *dest, const Byte *data, UInt32 size) return; } - int step = 2; if (size <= 8) { - step = -2; - dest += size * 2 - 2; + dest += size * 2; + for (UInt32 i = 0; i < size; i++) + { + const unsigned b = data[i]; + dest -= 2; + dest[0] = GetHex_Upper((b >> 4) & 0xF); + dest[1] = GetHex_Upper(b & 0xF); + } + } + else + { + for (UInt32 i = 0; i < size; i++) + { + const unsigned b = data[i]; + dest[0] = GetHex_Lower((b >> 4) & 0xF); + dest[1] = GetHex_Lower(b & 0xF); + dest += 2; + } + } +} + +void CHasherState::WriteToString(unsigned digestIndex, char *s) const +{ + HashHexToString(s, Digests[digestIndex], DigestSize); + + if (digestIndex != 0 && NumSums[digestIndex] != 1) + { + unsigned numExtraBytes = GetNumExtraBytes_for_Group(digestIndex); + if (numExtraBytes > 4) + numExtraBytes = 8; + else // if (numExtraBytes >= 0) + numExtraBytes = 4; + // if (numExtraBytes != 0) + { + s += strlen(s); + *s++ = '-'; + // *s = 0; + HashHexToString(s, GetExtraData_for_Group(digestIndex), numExtraBytes); + } + } +} + + + +// ---------- Hash Handler ---------- + +namespace NHash { + +static size_t ParseHexString(const char *s, Byte *dest) throw() +{ + size_t num; + for (num = 0;; num++, s += 2) + { + unsigned c = (Byte)s[0]; + unsigned v0; + if (c >= '0' && c <= '9') v0 = (c - '0'); + else if (c >= 'A' && c <= 'F') v0 = 10 + (c - 'A'); + else if (c >= 'a' && c <= 'f') v0 = 10 + (c - 'a'); + else + return num; + c = (Byte)s[1]; + unsigned v1; + if (c >= '0' && c <= '9') v1 = (c - '0'); + else if (c >= 'A' && c <= 'F') v1 = 10 + (c - 'A'); + else if (c >= 'a' && c <= 'f') v1 = 10 + (c - 'a'); + else + return num; + if (dest) + dest[num] = (Byte)(v1 | (v0 << 4)); + } +} + + +#define IsWhite(c) ((c) == ' ' || (c) == '\t') + +bool CHashPair::IsDir() const +{ + if (Name.IsEmpty() || Name.Back() != '/') + return false; + // here we expect that Dir items contain only zeros or no Hash + for (size_t i = 0; i < Hash.Size(); i++) + if (Hash[i] != 0) + return false; + return true; +} + + +bool CHashPair::ParseCksum(const char *s) +{ + const char *end; + + const UInt32 crc = ConvertStringToUInt32(s, &end); + if (*end != ' ') + return false; + end++; + + const UInt64 size = ConvertStringToUInt64(end, &end); + if (*end != ' ') + return false; + end++; + + Name = end; + + Hash.Alloc(4); + SetBe32(Hash, crc) + + Size_from_Arc = size; + Size_from_Arc_Defined = true; + + return true; +} + + + +static const char *SkipWhite(const char *s) +{ + while (IsWhite(*s)) + s++; + return s; +} + +static const char * const k_CsumMethodNames[] = +{ + "sha256" + , "sha224" +// , "sha512/224" +// , "sha512/256" + , "sha512" + , "sha384" + , "sha1" + , "md5" + , "blake2b" + , "crc64" + , "crc32" + , "cksum" +}; + +static UString GetMethod_from_FileName(const UString &name) +{ + AString s; + ConvertUnicodeToUTF8(name, s); + const int dotPos = s.ReverseFind_Dot(); + const char *src = s.Ptr(); + bool isExtension = false; + if (dotPos >= 0) + { + isExtension = true; + src = s.Ptr(dotPos + 1); + } + const char *m = ""; + unsigned i; + for (i = 0; i < Z7_ARRAY_SIZE(k_CsumMethodNames); i++) + { + m = k_CsumMethodNames[i]; + if (isExtension) + { + if (StringsAreEqual_Ascii(src, m)) + break; + } + else if (IsString1PrefixedByString2_NoCase_Ascii(src, m)) + if (StringsAreEqual_Ascii(src + strlen(m), "sums")) + break; + } + UString res; + if (i != Z7_ARRAY_SIZE(k_CsumMethodNames)) + res = m; + return res; +} + + +bool CHashPair::Parse(const char *s) +{ + // here we keep compatibility with original md5sum / shasum + bool escape = false; + + s = SkipWhite(s); + + if (*s == '\\') + { + s++; + escape = true; } - for (UInt32 i = 0; i < size; i++) + // const char *kMethod = GetMethod_from_FileName(s); + // if (kMethod) + if (ParseHexString(s, NULL) < 4) + { + // BSD-style checksum line + { + const char *s2 = s; + for (; *s2 != 0; s2++) + { + const char c = *s2; + if (c == 0) + return false; + if (c == ' ' || c == '(') + break; + } + Method.SetFrom(s, (unsigned)(s2 - s)); + s = s2; + } + IsBSD = true; + if (*s == ' ') + s++; + if (*s != '(') + return false; + s++; + { + const char *s2 = s; + for (; *s2 != 0; s2++) + {} + for (;;) + { + s2--; + if (s2 < s) + return false; + if (*s2 == ')') + break; + } + Name.SetFrom(s, (unsigned)(s2 - s)); + s = s2 + 1; + } + + s = SkipWhite(s); + if (*s != '=') + return false; + s++; + s = SkipWhite(s); + } + + { + const size_t num = ParseHexString(s, NULL); + Hash.Alloc(num); + ParseHexString(s, Hash); + const size_t numChars = num * 2; + HashString.SetFrom(s, (unsigned)numChars); + s += numChars; + } + + if (IsBSD) + { + if (*s != 0) + return false; + if (escape) + { + const AString temp (Name); + return CSum_Name_EscapeToOriginal(temp, Name); + } + return true; + } + + if (*s == 0) + return true; + + if (*s != ' ') + return false; + s++; + const char c = *s; + if (c != ' ' + && c != '*' + && c != 'U' // shasum Universal + && c != '^' // shasum 0/1 + ) + return false; + Mode = c; + s++; + if (escape) + return CSum_Name_EscapeToOriginal(s, Name); + Name = s; + return true; +} + + +static bool GetLine(CByteBuffer &buf, bool zeroMode, bool cr_lf_Mode, size_t &posCur, AString &s) +{ + s.Empty(); + size_t pos = posCur; + const Byte *p = buf; + unsigned numDigits = 0; + for (; pos < buf.Size(); pos++) + { + const Byte b = p[pos]; + if (b == 0) + { + numDigits = 1; + break; + } + if (zeroMode) + continue; + if (b == 0x0a) + { + numDigits = 1; + break; + } + if (!cr_lf_Mode) + continue; + if (b == 0x0d) + { + if (pos + 1 >= buf.Size()) + { + numDigits = 1; + break; + // return false; + } + if (p[pos + 1] == 0x0a) + { + numDigits = 2; + break; + } + } + } + s.SetFrom((const char *)(p + posCur), (unsigned)(pos - posCur)); + posCur = pos + numDigits; + return true; +} + + +static bool Is_CR_LF_Data(const Byte *buf, size_t size) +{ + bool isCrLf = false; + for (size_t i = 0; i < size;) + { + const Byte b = buf[i]; + if (b == 0x0a) + return false; + if (b == 0x0d) + { + if (i == size - 1) + return false; + if (buf[i + 1] != 0x0a) + return false; + isCrLf = true; + i += 2; + } + else + i++; + } + return isCrLf; +} + + +static const Byte kArcProps[] = +{ + // kpidComment, + kpidCharacts +}; + +static const Byte kProps[] = +{ + kpidPath, + kpidSize, + kpidPackSize, + kpidMethod +}; + +static const Byte kRawProps[] = +{ + kpidChecksum +}; + + +Z7_COM7F_IMF(CHandler::GetParent(UInt32 /* index */ , UInt32 *parent, UInt32 *parentType)) +{ + *parentType = NParentType::kDir; + *parent = (UInt32)(Int32)-1; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetNumRawProps(UInt32 *numProps)) +{ + *numProps = Z7_ARRAY_SIZE(kRawProps); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetRawPropInfo(UInt32 index, BSTR *name, PROPID *propID)) +{ + *propID = kRawProps[index]; + *name = NULL; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)) +{ + *data = NULL; + *dataSize = 0; + *propType = 0; + + if (propID == kpidChecksum) { - unsigned b = data[i]; - dest[0] = GetHex((b >> 4) & 0xF); - dest[1] = GetHex(b & 0xF); - dest += step; + const CHashPair &hp = HashPairs[index]; + if (hp.Hash.Size() > 0) + { + *data = hp.Hash; + *dataSize = (UInt32)hp.Hash.Size(); + *propType = NPropDataType::kRaw; + } + return S_OK; + } + + return S_OK; +} + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = HashPairs.Size(); + return S_OK; +} + +static void Add_OptSpace_String(UString &dest, const char *src) +{ + dest.Add_Space_if_NotEmpty(); + dest += src; +} + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + NWindows::NCOM::CPropVariant prop; + switch (propID) + { + case kpidPhySize: if (_phySize != 0) prop = _phySize; break; + /* + case kpidErrorFlags: + { + UInt32 v = 0; + if (!_isArc) v |= kpv_ErrorFlags_IsNotArc; + // if (_sres == k_Base64_RES_NeedMoreInput) v |= kpv_ErrorFlags_UnexpectedEnd; + if (v != 0) + prop = v; + break; + } + */ + case kpidCharacts: + { + UString s; + if (_hashSize_Defined) + { + s.Add_Space_if_NotEmpty(); + s.Add_UInt32(_hashSize * 8); + s += "-bit"; + } + if (!_nameExtenstion.IsEmpty()) + { + s.Add_Space_if_NotEmpty(); + s += _nameExtenstion; + } + if (_is_PgpMethod) + { + Add_OptSpace_String(s, "PGP"); + if (!_pgpMethod.IsEmpty()) + { + s += ":"; + s += _pgpMethod; + } + } + if (_is_ZeroMode) + Add_OptSpace_String(s, "ZERO"); + if (_are_there_Tags) + Add_OptSpace_String(s, "TAG"); + if (_are_there_Dirs) + Add_OptSpace_String(s, "DIRS"); + prop = s; + break; + } + + case kpidReadOnly: + { + if (_isArc) + if (!CanUpdate()) + prop = true; + break; + } + } + prop.Detach(value); + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + // COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + CHashPair &hp = HashPairs[index]; + switch (propID) + { + case kpidIsDir: + { + prop = hp.IsDir(); + break; + } + case kpidPath: + { + UString path; + hp.Get_UString_Path(path); + + NArchive::NItemName::ReplaceToOsSlashes_Remove_TailSlash(path, + true); // useBackslashReplacement + + prop = path; + break; + } + case kpidSize: + { + // client needs processed size of last file + if (hp.Size_from_Disk_Defined) + prop = (UInt64)hp.Size_from_Disk; + else if (hp.Size_from_Arc_Defined) + prop = (UInt64)hp.Size_from_Arc; + break; + } + case kpidPackSize: + { + prop = (UInt64)hp.Hash.Size(); + break; + } + case kpidMethod: + { + if (!hp.Method.IsEmpty()) + prop = hp.Method; + break; + } + } + prop.Detach(value); + return S_OK; + // COM_TRY_END +} + + +static HRESULT ReadStream_to_Buf(IInStream *stream, CByteBuffer &buf, IArchiveOpenCallback *openCallback) +{ + buf.Free(); + UInt64 len; + RINOK(InStream_AtBegin_GetSize(stream, len)) + if (len == 0 || len >= ((UInt64)1 << 31)) + return S_FALSE; + buf.Alloc((size_t)len); + UInt64 pos = 0; + // return ReadStream_FALSE(stream, buf, (size_t)len); + for (;;) + { + const UInt32 kBlockSize = ((UInt32)1 << 24); + const UInt32 curSize = (len < kBlockSize) ? (UInt32)len : kBlockSize; + UInt32 processedSizeLoc; + RINOK(stream->Read((Byte *)buf + pos, curSize, &processedSizeLoc)) + if (processedSizeLoc == 0) + return E_FAIL; + len -= processedSizeLoc; + pos += processedSizeLoc; + if (len == 0) + return S_OK; + if (openCallback) + { + const UInt64 files = 0; + RINOK(openCallback->SetCompleted(&files, &pos)) + } + } +} + + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *openCallback)) +{ + COM_TRY_BEGIN + { + Close(); + + CByteBuffer buf; + RINOK(ReadStream_to_Buf(stream, buf, openCallback)) + + CObjectVector<CHashPair> &pairs = HashPairs; + + bool zeroMode = false; + bool cr_lf_Mode = false; + { + for (size_t i = 0; i < buf.Size(); i++) + if (buf[i] == 0) + { + zeroMode = true; + break; + } + } + _is_ZeroMode = zeroMode; + if (!zeroMode) + cr_lf_Mode = Is_CR_LF_Data(buf, buf.Size()); + + if (openCallback) + { + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveOpenVolumeCallback, + openVolumeCallback, openCallback) + if (openVolumeCallback) + { + NCOM::CPropVariant prop; + RINOK(openVolumeCallback->GetProperty(kpidName, &prop)) + if (prop.vt == VT_BSTR) + _nameExtenstion = GetMethod_from_FileName(prop.bstrVal); + } + } + + bool cksumMode = false; + if (_nameExtenstion.IsEqualTo_Ascii_NoCase("cksum")) + cksumMode = true; + _is_CksumMode = cksumMode; + + size_t pos = 0; + AString s; + bool minusMode = false; + unsigned numLines = 0; + + while (pos < buf.Size()) + { + if (!GetLine(buf, zeroMode, cr_lf_Mode, pos, s)) + return S_FALSE; + numLines++; + if (s.IsEmpty()) + continue; + + if (s.IsPrefixedBy_Ascii_NoCase("; ")) + { + if (numLines != 1) + return S_FALSE; + // comment line of FileVerifier++ + continue; + } + + if (s.IsPrefixedBy_Ascii_NoCase("-----")) + { + if (minusMode) + break; // end of pgp mode + minusMode = true; + if (s.IsPrefixedBy_Ascii_NoCase("-----BEGIN PGP SIGNED MESSAGE")) + { + if (_is_PgpMethod) + return S_FALSE; + if (!GetLine(buf, zeroMode, cr_lf_Mode, pos, s)) + return S_FALSE; + const char *kStart = "Hash: "; + if (!s.IsPrefixedBy_Ascii_NoCase(kStart)) + return S_FALSE; + _pgpMethod = s.Ptr((unsigned)strlen(kStart)); + _is_PgpMethod = true; + } + continue; + } + + CHashPair pair; + pair.FullLine = s; + if (cksumMode) + { + if (!pair.ParseCksum(s)) + return S_FALSE; + } + else if (!pair.Parse(s)) + return S_FALSE; + pairs.Add(pair); + } + + { + unsigned hashSize = 0; + bool hashSize_Dismatch = false; + for (unsigned i = 0; i < HashPairs.Size(); i++) + { + const CHashPair &hp = HashPairs[i]; + if (i == 0) + hashSize = (unsigned)hp.Hash.Size(); + else + if (hashSize != hp.Hash.Size()) + hashSize_Dismatch = true; + + if (hp.IsBSD) + _are_there_Tags = true; + if (!_are_there_Dirs && hp.IsDir()) + _are_there_Dirs = true; + } + if (!hashSize_Dismatch && hashSize != 0) + { + _hashSize = hashSize; + _hashSize_Defined = true; + } + } + + _phySize = buf.Size(); + _isArc = true; + return S_OK; + } + COM_TRY_END +} + + +void CHandler::ClearVars() +{ + _phySize = 0; + _isArc = false; + _is_CksumMode = false; + _is_PgpMethod = false; + _is_ZeroMode = false; + _are_there_Tags = false; + _are_there_Dirs = false; + _hashSize_Defined = false; + _hashSize = 0; +} + + +Z7_COM7F_IMF(CHandler::Close()) +{ + ClearVars(); + _nameExtenstion.Empty(); + _pgpMethod.Empty(); + HashPairs.Clear(); + return S_OK; +} + + +static bool CheckDigests(const Byte *a, const Byte *b, size_t size) +{ + if (size <= 8) + { + /* we use reversed order for one digest, when text representation + uses big-order for crc-32 and crc-64 */ + for (size_t i = 0; i < size; i++) + if (a[i] != b[size - 1 - i]) + return false; + return true; + } + { + for (size_t i = 0; i < size; i++) + if (a[i] != b[i]) + return false; + return true; + } +} + + +static void AddDefaultMethod(UStringVector &methods, unsigned size) +{ + const char *m = NULL; + if (size == 32) m = "sha256"; + else if (size == 20) m = "sha1"; + else if (size == 16) m = "md5"; + else if (size == 8) m = "crc64"; + else if (size == 4) m = "crc32"; + else + return; + #ifdef Z7_EXTERNAL_CODECS + const CExternalCodecs *_externalCodecs = g_ExternalCodecs_Ptr; + #endif + CMethodId id; + if (FindHashMethod(EXTERNAL_CODECS_LOC_VARS + AString(m), id)) + methods.Add(UString(m)); +} + + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) +{ + COM_TRY_BEGIN + + /* + if (testMode == 0) + return E_NOTIMPL; + */ + + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); + if (allFilesMode) + numItems = HashPairs.Size(); + if (numItems == 0) + return S_OK; + + #ifdef Z7_EXTERNAL_CODECS + const CExternalCodecs *_externalCodecs = g_ExternalCodecs_Ptr; + #endif + + CHashBundle hb_Glob; + // UStringVector methods = options.Methods; + UStringVector methods; + + if (methods.IsEmpty() && !_nameExtenstion.IsEmpty()) + { + AString utf; + ConvertUnicodeToUTF8(_nameExtenstion, utf); + CMethodId id; + if (FindHashMethod(EXTERNAL_CODECS_LOC_VARS utf, id)) + methods.Add(_nameExtenstion); + } + + if (methods.IsEmpty() && !_pgpMethod.IsEmpty()) + { + CMethodId id; + if (FindHashMethod(EXTERNAL_CODECS_LOC_VARS _pgpMethod, id)) + methods.Add(UString(_pgpMethod)); + } + + if (methods.IsEmpty() && _pgpMethod.IsEmpty() && _hashSize_Defined) + AddDefaultMethod(methods, _hashSize); + + RINOK(hb_Glob.SetMethods( + EXTERNAL_CODECS_LOC_VARS + methods)) + + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveUpdateCallbackFile, + updateCallbackFile, extractCallback) + if (!updateCallbackFile) + return E_NOTIMPL; + { + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveGetDiskProperty, + GetDiskProperty, extractCallback) + if (GetDiskProperty) + { + UInt64 totalSize = 0; + UInt32 i; + for (i = 0; i < numItems; i++) + { + const UInt32 index = allFilesMode ? i : indices[i]; + const CHashPair &hp = HashPairs[index]; + if (hp.IsDir()) + continue; + { + NCOM::CPropVariant prop; + RINOK(GetDiskProperty->GetDiskProperty(index, kpidSize, &prop)) + if (prop.vt != VT_UI8) + continue; + totalSize += prop.uhVal.QuadPart; + } + } + RINOK(extractCallback->SetTotal(totalSize)) + // RINOK(Hash_SetTotalUnpacked->Hash_SetTotalUnpacked(indices, numItems)); + } + } + + const UInt32 kBufSize = 1 << 15; + CHashMidBuf buf; + if (!buf.Alloc(kBufSize)) + return E_OUTOFMEMORY; + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr<ICompressProgressInfo> progress = lps; + lps->Init(extractCallback, false); + lps->InSize = lps->OutSize = 0; + + UInt32 i; + for (i = 0; i < numItems; i++) + { + RINOK(lps->SetCur()) + const UInt32 index = allFilesMode ? i : indices[i]; + + CHashPair &hp = HashPairs[index]; + + UString path; + hp.Get_UString_Path(path); + + CMyComPtr<ISequentialInStream> inStream; + const bool isDir = hp.IsDir(); + if (!isDir) + { + RINOK(updateCallbackFile->GetStream2(index, &inStream, NUpdateNotifyOp::kHashRead)) + if (!inStream) + { + continue; // we have shown error in GetStream2() + } + // askMode = NArchive::NExtract::NAskMode::kSkip; + } + + Int32 askMode = testMode ? + NArchive::NExtract::NAskMode::kTest : + NArchive::NExtract::NAskMode::kExtract; + + CMyComPtr<ISequentialOutStream> realOutStream; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) + + /* PrepareOperation() can expect kExtract to set + Attrib and security of output file */ + askMode = NArchive::NExtract::NAskMode::kReadExternal; + + extractCallback->PrepareOperation(askMode); + + const bool isAltStream = false; + + UInt64 fileSize = 0; + + CHashBundle hb_Loc; + + CHashBundle *hb_Use = &hb_Glob; + + HRESULT res_SetMethods = S_OK; + + UStringVector methods_loc; + + if (!hp.Method.IsEmpty()) + { + hb_Use = &hb_Loc; + CMethodId id; + if (FindHashMethod(EXTERNAL_CODECS_LOC_VARS hp.Method, id)) + { + methods_loc.Add(UString(hp.Method)); + RINOK(hb_Loc.SetMethods( + EXTERNAL_CODECS_LOC_VARS + methods_loc)) + } + else + res_SetMethods = E_NOTIMPL; + } + else if (methods.IsEmpty()) + { + AddDefaultMethod(methods_loc, (unsigned)hp.Hash.Size()); + if (!methods_loc.IsEmpty()) + { + hb_Use = &hb_Loc; + RINOK(hb_Loc.SetMethods( + EXTERNAL_CODECS_LOC_VARS + methods_loc)) + } + } + + const bool isSupportedMode = hp.IsSupportedMode(); + hb_Use->InitForNewFile(); + + if (inStream) + { + for (UInt32 step = 0;; step++) + { + if ((step & 0xFF) == 0) + { + RINOK(progress->SetRatioInfo(NULL, &fileSize)) + } + UInt32 size; + RINOK(inStream->Read(buf, kBufSize, &size)) + if (size == 0) + break; + hb_Use->Update(buf, size); + if (realOutStream) + { + RINOK(WriteStream(realOutStream, buf, size)) + } + fileSize += size; + } + + hp.Size_from_Disk = fileSize; + hp.Size_from_Disk_Defined = true; + } + + realOutStream.Release(); + inStream.Release(); + + lps->InSize += hp.Hash.Size(); + lps->OutSize += fileSize; + + hb_Use->Final(isDir, isAltStream, path); + + Int32 opRes = NArchive::NExtract::NOperationResult::kUnsupportedMethod; + if (isSupportedMode + && res_SetMethods != E_NOTIMPL + && hb_Use->Hashers.Size() > 0 + ) + { + const CHasherState &hs = hb_Use->Hashers[0]; + if (hs.DigestSize == hp.Hash.Size()) + { + opRes = NArchive::NExtract::NOperationResult::kCRCError; + if (CheckDigests(hp.Hash, hs.Digests[0], hs.DigestSize)) + if (!hp.Size_from_Arc_Defined || hp.Size_from_Arc == fileSize) + opRes = NArchive::NExtract::NOperationResult::kOK; + } + } + + RINOK(extractCallback->SetOperationResult(opRes)) + } + + return lps->SetCur(); + + COM_TRY_END +} + + +// ---------- UPDATE ---------- + +struct CUpdateItem +{ + int IndexInArc; + unsigned IndexInClient; + UInt64 Size; + bool NewData; + bool NewProps; + bool IsDir; + UString Path; + + CUpdateItem(): Size(0), IsDir(false) {} +}; + + +static HRESULT GetPropString(IArchiveUpdateCallback *callback, UInt32 index, PROPID propId, + UString &res, + bool convertSlash) +{ + NCOM::CPropVariant prop; + RINOK(callback->GetProperty(index, propId, &prop)) + if (prop.vt == VT_BSTR) + { + res = prop.bstrVal; + if (convertSlash) + NArchive::NItemName::ReplaceSlashes_OsToUnix(res); + } + else if (prop.vt != VT_EMPTY) + return E_INVALIDARG; + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::GetFileTimeType(UInt32 *type)) +{ + *type = NFileTimeType::kUnix; + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, + IArchiveUpdateCallback *callback)) +{ + COM_TRY_BEGIN + + if (_isArc && !CanUpdate()) + return E_NOTIMPL; + + /* + Z7_DECL_CMyComPtr_QI_FROM(IArchiveUpdateCallbackArcProp, + reportArcProp, callback) + */ + + CObjectVector<CUpdateItem> updateItems; + + UInt64 complexity = 0; + + UInt32 i; + for (i = 0; i < numItems; i++) + { + CUpdateItem ui; + Int32 newData; + Int32 newProps; + UInt32 indexInArc; + + if (!callback) + return E_FAIL; + + RINOK(callback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArc)) + + ui.NewProps = IntToBool(newProps); + ui.NewData = IntToBool(newData); + ui.IndexInArc = (int)indexInArc; + ui.IndexInClient = i; + if (IntToBool(newProps)) + { + { + NCOM::CPropVariant prop; + RINOK(callback->GetProperty(i, kpidIsDir, &prop)) + if (prop.vt == VT_EMPTY) + ui.IsDir = false; + else if (prop.vt != VT_BOOL) + return E_INVALIDARG; + else + ui.IsDir = (prop.boolVal != VARIANT_FALSE); + } + + RINOK(GetPropString(callback, i, kpidPath, ui.Path, + true)) // convertSlash + /* + if (ui.IsDir && !ui.Name.IsEmpty() && ui.Name.Back() != '/') + ui.Name += '/'; + */ + } + + if (IntToBool(newData)) + { + NCOM::CPropVariant prop; + RINOK(callback->GetProperty(i, kpidSize, &prop)) + if (prop.vt == VT_UI8) + { + ui.Size = prop.uhVal.QuadPart; + complexity += ui.Size; + } + else if (prop.vt == VT_EMPTY) + ui.Size = (UInt64)(Int64)-1; + else + return E_INVALIDARG; + } + + updateItems.Add(ui); + } + + if (complexity != 0) + { + RINOK(callback->SetTotal(complexity)) + } + + #ifdef Z7_EXTERNAL_CODECS + const CExternalCodecs *_externalCodecs = g_ExternalCodecs_Ptr; + #endif + + CHashBundle hb; + UStringVector methods; + if (!_methods.IsEmpty()) + { + FOR_VECTOR(k, _methods) + { + methods.Add(_methods[k]); + } + } + else if (_crcSize_WasSet) + { + AddDefaultMethod(methods, _crcSize); + } + else + { + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveGetRootProps, + getRootProps, callback) + if (getRootProps) + { + NCOM::CPropVariant prop; + RINOK(getRootProps->GetRootProp(kpidArcFileName, &prop)) + if (prop.vt == VT_BSTR) + { + const UString method = GetMethod_from_FileName(prop.bstrVal); + if (!method.IsEmpty()) + methods.Add(method); + } + } + } + + RINOK(hb.SetMethods(EXTERNAL_CODECS_LOC_VARS methods)) + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr<ICompressProgressInfo> progress = lps; + lps->Init(callback, true); + + const UInt32 kBufSize = 1 << 15; + CHashMidBuf buf; + if (!buf.Alloc(kBufSize)) + return E_OUTOFMEMORY; + + CDynLimBuf hashFileString((size_t)1 << 31); + + CHashOptionsLocal options = _options; + + if (_isArc) + { + if (!options.HashMode_Zero.Def && _is_ZeroMode) + options.HashMode_Zero.Val = true; + if (!options.HashMode_Tag.Def && _are_there_Tags) + options.HashMode_Tag.Val = true; + if (!options.HashMode_Dirs.Def && _are_there_Dirs) + options.HashMode_Dirs.Val = true; + } + if (options.HashMode_OnlyHash.Val && updateItems.Size() != 1) + options.HashMode_OnlyHash.Val = false; + + lps->OutSize = 0; + complexity = 0; + + for (i = 0; i < updateItems.Size(); i++) + { + lps->InSize = complexity; + RINOK(lps->SetCur()) + + const CUpdateItem &ui = updateItems[i]; + + /* + CHashPair item; + if (!ui.NewProps) + item = HashPairs[(unsigned)ui.IndexInArc]; + */ + + if (ui.NewData) + { + UInt64 currentComplexity = ui.Size; + UInt64 fileSize = 0; + + CMyComPtr<ISequentialInStream> fileInStream; + bool needWrite = true; + { + HRESULT res = callback->GetStream(ui.IndexInClient, &fileInStream); + + if (res == S_FALSE) + needWrite = false; + else + { + RINOK(res) + + if (fileInStream) + { + Z7_DECL_CMyComPtr_QI_FROM( + IStreamGetSize, + streamGetSize, fileInStream) + if (streamGetSize) + { + UInt64 size; + if (streamGetSize->GetSize(&size) == S_OK) + currentComplexity = size; + } + /* + Z7_DECL_CMyComPtr_QI_FROM( + IStreamGetProps, + getProps, fileInStream) + if (getProps) + { + FILETIME mTime; + UInt64 size2; + if (getProps->GetProps(&size2, NULL, NULL, &mTime, NULL) == S_OK) + { + currentComplexity = size2; + // item.MTime = NWindows::NTime::FileTimeToUnixTime64(mTime);; + } + } + */ + } + else + { + currentComplexity = 0; + } + } + } + + hb.InitForNewFile(); + const bool isDir = ui.IsDir; + + if (needWrite && fileInStream && !isDir) + { + for (UInt32 step = 0;; step++) + { + if ((step & 0xFF) == 0) + { + RINOK(progress->SetRatioInfo(&fileSize, NULL)) + // RINOK(callback->SetCompleted(&completeValue)); + } + UInt32 size; + RINOK(fileInStream->Read(buf, kBufSize, &size)) + if (size == 0) + break; + hb.Update(buf, size); + fileSize += size; + } + currentComplexity = fileSize; + } + + fileInStream.Release(); + const bool isAltStream = false; + hb.Final(isDir, isAltStream, ui.Path); + + if (options.HashMode_Dirs.Val || !isDir) + { + if (!hb.Hashers.IsEmpty()) + lps->OutSize += hb.Hashers[0].DigestSize; + WriteLine(hashFileString, + options, + ui.Path, + isDir, + hb); + if (hashFileString.IsError()) + return E_OUTOFMEMORY; + } + + complexity += currentComplexity; + + /* + if (reportArcProp) + { + PROPVARIANT prop; + prop.vt = VT_EMPTY; + prop.wReserved1 = 0; + + NCOM::PropVarEm_Set_UInt64(&prop, fileSize); + RINOK(reportArcProp->ReportProp(NArchive::NEventIndexType::kOutArcIndex, ui.IndexInClient, kpidSize, &prop)); + + for (unsigned k = 0; k < hb.Hashers.Size(); k++) + { + const CHasherState &hs = hb.Hashers[k]; + + if (hs.DigestSize == 4 && hs.Name.IsEqualTo_Ascii_NoCase("crc32")) + { + NCOM::PropVarEm_Set_UInt32(&prop, GetUi32(hs.Digests[k_HashCalc_Index_Current])); + RINOK(reportArcProp->ReportProp(NArchive::NEventIndexType::kOutArcIndex, ui.IndexInClient, kpidCRC, &prop)); + } + else + { + RINOK(reportArcProp->ReportRawProp(NArchive::NEventIndexType::kOutArcIndex, ui.IndexInClient, + kpidChecksum, hs.Digests[k_HashCalc_Index_Current], + hs.DigestSize, NPropDataType::kRaw)); + } + RINOK(reportArcProp->ReportFinished(NArchive::NEventIndexType::kOutArcIndex, ui.IndexInClient, NArchive::NUpdate::NOperationResult::kOK)); + } + } + */ + RINOK(callback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)) + } + else + { + // old data + const CHashPair &existItem = HashPairs[(unsigned)ui.IndexInArc]; + if (ui.NewProps) + { + WriteLine(hashFileString, + options, + ui.Path, + ui.IsDir, + existItem.Method, existItem.HashString + ); + } + else + { + hashFileString += existItem.FullLine; + Add_LF(hashFileString, options); + } + } + if (hashFileString.IsError()) + return E_OUTOFMEMORY; + } + + RINOK(WriteStream(outStream, hashFileString, hashFileString.Len())) + + return S_OK; + COM_TRY_END +} + + + +HRESULT CHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value) +{ + UString name = nameSpec; + name.MakeLower_Ascii(); + if (name.IsEmpty()) + return E_INVALIDARG; + + if (name.IsEqualTo("m")) // "hm" hash method + { + // COneMethodInfo omi; + // RINOK(omi.ParseMethodFromPROPVARIANT(L"", value)); + // _methods.Add(omi.MethodName); // change it. use omi.PropsString + if (value.vt != VT_BSTR) + return E_INVALIDARG; + UString s (value.bstrVal); + _methods.Add(s); + return S_OK; + } + + if (name.IsEqualTo("flags")) + { + if (value.vt != VT_BSTR) + return E_INVALIDARG; + if (!_options.ParseString(value.bstrVal)) + return E_INVALIDARG; + return S_OK; + } + + if (name.IsPrefixedBy_Ascii_NoCase("crc")) + { + name.Delete(0, 3); + _crcSize = 4; + _crcSize_WasSet = true; + return ParsePropToUInt32(name, value, _crcSize); + } + + // common properties + if (name.IsPrefixedBy_Ascii_NoCase("mt") + || name.IsPrefixedBy_Ascii_NoCase("memuse")) + return S_OK; + + return E_INVALIDARG; +} + + +Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)) +{ + COM_TRY_BEGIN + + InitProps(); + + for (UInt32 i = 0; i < numProps; i++) + { + RINOK(SetProperty(names[i], values[i])) + } + return S_OK; + COM_TRY_END +} + +CHandler::CHandler() +{ + ClearVars(); + InitProps(); +} + +} + + + +static IInArchive *CreateHashHandler_In() { return new NHash::CHandler; } +static IOutArchive *CreateHashHandler_Out() { return new NHash::CHandler; } + +void Codecs_AddHashArcHandler(CCodecs *codecs) +{ + { + CArcInfoEx item; + + item.Name = "Hash"; + item.CreateInArchive = CreateHashHandler_In; + item.CreateOutArchive = CreateHashHandler_Out; + item.IsArcFunc = NULL; + item.Flags = + NArcInfoFlags::kKeepName + | NArcInfoFlags::kStartOpen + | NArcInfoFlags::kByExtOnlyOpen + // | NArcInfoFlags::kPureStartOpen + | NArcInfoFlags::kHashHandler + ; + + // ubuntu uses "SHA256SUMS" file + item.AddExts(UString ( + "sha256 sha512 sha224 sha384 sha1 sha md5" + // "b2sum" + " crc32 crc64" + " asc" + " cksum" + ), + UString()); + + item.UpdateEnabled = (item.CreateOutArchive != NULL); + item.SignatureOffset = 0; + // item.Version = MY_VER_MIX; + item.NewInterface = true; + + item.Signatures.AddNew().CopyFrom(NULL, 0); + + codecs->Formats.Add(item); } } diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/HashCalc.h b/3rdparty/lzma/CPP/7zip/UI/Common/HashCalc.h index 38908e2e8b3..0b527c16497 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/HashCalc.h +++ b/3rdparty/lzma/CPP/7zip/UI/Common/HashCalc.h @@ -1,20 +1,27 @@ // HashCalc.h -#ifndef __HASH_CALC_H -#define __HASH_CALC_H +#ifndef ZIP7_INC_HASH_CALC_H +#define ZIP7_INC_HASH_CALC_H +#include "../../../Common/UTFConvert.h" #include "../../../Common/Wildcard.h" #include "../../Common/CreateCoder.h" #include "../../Common/MethodProps.h" #include "DirItem.h" -#include "Property.h" +#include "IFileExtractCallback.h" const unsigned k_HashCalc_DigestSize_Max = 64; - +const unsigned k_HashCalc_ExtraSize = 8; const unsigned k_HashCalc_NumGroups = 4; +/* + if (size <= 8) : upper case : reversed byte order : it shows 32-bit/64-bit number, if data contains little-endian number + if (size > 8) : lower case : original byte order (as big-endian byte sequence) +*/ +void HashHexToString(char *dest, const Byte *data, UInt32 size); + enum { k_HashCalc_Index_Current, @@ -28,10 +35,40 @@ struct CHasherState CMyComPtr<IHasher> Hasher; AString Name; UInt32 DigestSize; - Byte Digests[k_HashCalc_NumGroups][k_HashCalc_DigestSize_Max]; + UInt64 NumSums[k_HashCalc_NumGroups]; + Byte Digests[k_HashCalc_NumGroups][k_HashCalc_DigestSize_Max + k_HashCalc_ExtraSize]; + + void InitDigestGroup(unsigned groupIndex) + { + NumSums[groupIndex] = 0; + memset(Digests[groupIndex], 0, sizeof(Digests[groupIndex])); + } + + const Byte *GetExtraData_for_Group(unsigned groupIndex) const + { + return Digests[groupIndex] + k_HashCalc_DigestSize_Max; + } + + unsigned GetNumExtraBytes_for_Group(unsigned groupIndex) const + { + const Byte *p = GetExtraData_for_Group(groupIndex); + // we use little-endian to read extra bytes + for (unsigned i = k_HashCalc_ExtraSize; i != 0; i--) + if (p[i - 1] != 0) + return i; + return 0; + } + + void AddDigest(unsigned groupIndex, const Byte *data); + + void WriteToString(unsigned digestIndex, char *s) const; }; -struct IHashCalc + +Z7_PURE_INTERFACES_BEGIN + + +DECLARE_INTERFACE(IHashCalc) { virtual void InitForNewFile() = 0; virtual void Update(const void *data, UInt32 size) = 0; @@ -39,7 +76,9 @@ struct IHashCalc virtual void Final(bool isDir, bool isAltStream, const UString &path) = 0; }; -struct CHashBundle: public IHashCalc +Z7_PURE_INTERFACES_END + +struct CHashBundle Z7_final: public IHashCalc { CObjectVector<CHasherState> Hashers; @@ -52,49 +91,123 @@ struct CHashBundle: public IHashCalc UInt64 CurSize; + UString MainName; + UString FirstFileName; + HRESULT SetMethods(DECL_EXTERNAL_CODECS_LOC_VARS const UStringVector &methods); - void Init() + // void Init() {} + CHashBundle() { NumDirs = NumFiles = NumAltStreams = FilesSize = AltStreamsSize = NumErrors = 0; } - void InitForNewFile(); - void Update(const void *data, UInt32 size); - void SetSize(UInt64 size); - void Final(bool isDir, bool isAltStream, const UString &path); + void InitForNewFile() Z7_override; + void Update(const void *data, UInt32 size) Z7_override; + void SetSize(UInt64 size) Z7_override; + void Final(bool isDir, bool isAltStream, const UString &path) Z7_override; }; -#define INTERFACE_IHashCallbackUI(x) \ - INTERFACE_IDirItemsCallback(x) \ - virtual HRESULT StartScanning() x; \ - virtual HRESULT FinishScanning(const CDirItemsStat &st) x; \ - virtual HRESULT SetNumFiles(UInt64 numFiles) x; \ - virtual HRESULT SetTotal(UInt64 size) x; \ - virtual HRESULT SetCompleted(const UInt64 *completeValue) x; \ - virtual HRESULT CheckBreak() x; \ - virtual HRESULT BeforeFirstFile(const CHashBundle &hb) x; \ - virtual HRESULT GetStream(const wchar_t *name, bool isFolder) x; \ - virtual HRESULT OpenFileError(const FString &path, DWORD systemError) x; \ - virtual HRESULT SetOperationResult(UInt64 fileSize, const CHashBundle &hb, bool showHash) x; \ - virtual HRESULT AfterLastFile(const CHashBundle &hb) x; \ - -struct IHashCallbackUI: public IDirItemsCallback +Z7_PURE_INTERFACES_BEGIN + +// INTERFACE_IDirItemsCallback(x) + +#define Z7_IFACEN_IHashCallbackUI(x) \ + virtual HRESULT StartScanning() x \ + virtual HRESULT FinishScanning(const CDirItemsStat &st) x \ + virtual HRESULT SetNumFiles(UInt64 numFiles) x \ + virtual HRESULT SetTotal(UInt64 size) x \ + virtual HRESULT SetCompleted(const UInt64 *completeValue) x \ + virtual HRESULT CheckBreak() x \ + virtual HRESULT BeforeFirstFile(const CHashBundle &hb) x \ + virtual HRESULT GetStream(const wchar_t *name, bool isFolder) x \ + virtual HRESULT OpenFileError(const FString &path, DWORD systemError) x \ + virtual HRESULT SetOperationResult(UInt64 fileSize, const CHashBundle &hb, bool showHash) x \ + virtual HRESULT AfterLastFile(CHashBundle &hb) x \ + +Z7_IFACE_DECL_PURE_(IHashCallbackUI, IDirItemsCallback) + +Z7_PURE_INTERFACES_END + + +struct CHashOptionsLocal { - INTERFACE_IHashCallbackUI(=0) + CBoolPair HashMode_Zero; + CBoolPair HashMode_Tag; + CBoolPair HashMode_Dirs; + CBoolPair HashMode_OnlyHash; + + void Init_HashOptionsLocal() + { + HashMode_Zero.Init(); + HashMode_Tag.Init(); + HashMode_Dirs.Init(); + HashMode_OnlyHash.Init(); + // HashMode_Dirs = true; // for debug + } + + CHashOptionsLocal() + { + Init_HashOptionsLocal(); + } + + bool ParseFlagCharOption(wchar_t c, bool val) + { + c = MyCharLower_Ascii(c); + if (c == 'z') HashMode_Zero.SetVal_as_Defined(val); + else if (c == 't') HashMode_Tag.SetVal_as_Defined(val); + else if (c == 'd') HashMode_Dirs.SetVal_as_Defined(val); + else if (c == 'h') HashMode_OnlyHash.SetVal_as_Defined(val); + else return false; + return true; + } + + bool ParseString(const UString &s) + { + for (unsigned i = 0; i < s.Len();) + { + const wchar_t c = s[i++]; + bool val = true; + if (i < s.Len()) + { + const wchar_t next = s[i]; + if (next == '-') + { + val = false; + i++; + } + } + if (!ParseFlagCharOption(c, val)) + return false; + } + return true; + } }; + struct CHashOptions + // : public CHashOptionsLocal { UStringVector Methods; + // UString HashFilePath; + + bool PreserveATime; bool OpenShareForWrite; bool StdInMode; bool AltStreamsMode; + CBoolPair SymLinks; + NWildcard::ECensorPathMode PathMode; - - CHashOptions(): StdInMode(false), OpenShareForWrite(false), AltStreamsMode(false), PathMode(NWildcard::k_RelatPath) {}; + + CHashOptions(): + PreserveATime(false), + OpenShareForWrite(false), + StdInMode(false), + AltStreamsMode(false), + PathMode(NWildcard::k_RelatPath) {} }; + HRESULT HashCalc( DECL_EXTERNAL_CODECS_LOC_VARS const NWildcard::CCensor &censor, @@ -102,6 +215,114 @@ HRESULT HashCalc( AString &errorInfo, IHashCallbackUI *callback); -void AddHashHexToString(char *dest, const Byte *data, UInt32 size); + + +#ifndef Z7_SFX + +namespace NHash { + +struct CHashPair +{ + CByteBuffer Hash; + char Mode; + bool IsBSD; + bool Size_from_Arc_Defined; + bool Size_from_Disk_Defined; + AString Method; + AString Name; + + AString FullLine; + AString HashString; + // unsigned HashLengthInBits; + + // AString MethodName; + UInt64 Size_from_Arc; + UInt64 Size_from_Disk; + + bool IsDir() const; + + void Get_UString_Path(UString &path) const + { + path.Empty(); + if (!ConvertUTF8ToUnicode(Name, path)) + return; + } + + bool ParseCksum(const char *s); + bool Parse(const char *s); + + bool IsSupportedMode() const + { + return Mode != 'U' && Mode != '^'; + } + + CHashPair(): + Mode(0) + , IsBSD(false) + , Size_from_Arc_Defined(false) + , Size_from_Disk_Defined(false) + // , HashLengthInBits(0) + , Size_from_Arc(0) + , Size_from_Disk(0) + {} +}; + + +Z7_CLASS_IMP_CHandler_IInArchive_3( + IArchiveGetRawProps, + /* public IGetArchiveHashHandler, */ + IOutArchive, + ISetProperties +) + bool _isArc; + UInt64 _phySize; + CObjectVector<CHashPair> HashPairs; + UString _nameExtenstion; + // UString _method_fromName; + AString _pgpMethod; + bool _is_CksumMode; + bool _is_PgpMethod; + bool _is_ZeroMode; + bool _are_there_Tags; + bool _are_there_Dirs; + bool _hashSize_Defined; + unsigned _hashSize; + + bool _crcSize_WasSet; + UInt32 _crcSize; + UStringVector _methods; + + void ClearVars(); + + void InitProps() + { + _crcSize_WasSet = false; + _crcSize = 4; + _methods.Clear(); + _options.Init_HashOptionsLocal(); + } + + CHashOptionsLocal _options; + + bool CanUpdate() const + { + if (!_isArc || _is_PgpMethod || _is_CksumMode) + return false; + return true; + + } + + HRESULT SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value); + +public: + CHandler(); +}; + +} + +void Codecs_AddHashArcHandler(CCodecs *codecs); + +#endif + #endif diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/IFileExtractCallback.h b/3rdparty/lzma/CPP/7zip/UI/Common/IFileExtractCallback.h index c456c862737..dd5c0d7214e 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/IFileExtractCallback.h +++ b/3rdparty/lzma/CPP/7zip/UI/Common/IFileExtractCallback.h @@ -1,7 +1,7 @@ // IFileExtractCallback.h -#ifndef __I_FILE_EXTRACT_CALLBACK_H -#define __I_FILE_EXTRACT_CALLBACK_H +#ifndef ZIP7_INC_I_FILE_EXTRACT_CALLBACK_H +#define ZIP7_INC_I_FILE_EXTRACT_CALLBACK_H #include "../../../Common/MyString.h" @@ -10,6 +10,15 @@ #include "LoadCodecs.h" #include "OpenArchive.h" +Z7_PURE_INTERFACES_BEGIN + +#define Z7_IFACE_CONSTR_FOLDERARC_SUB(i, base, n) \ + Z7_DECL_IFACE_7ZIP_SUB(i, base, 1, n) \ + { Z7_IFACE_COM7_PURE(i) }; + +#define Z7_IFACE_CONSTR_FOLDERARC(i, n) \ + Z7_IFACE_CONSTR_FOLDERARC_SUB(i, IUnknown, n) + namespace NOverwriteAnswer { enum EEnum @@ -42,27 +51,21 @@ IID_IFolderArchiveExtractCallback is requested by: IFolderArchiveExtractCallback is used by Common/ArchiveExtractCallback.cpp */ -#define INTERFACE_IFolderArchiveExtractCallback(x) \ - STDMETHOD(AskOverwrite)( \ +#define Z7_IFACEM_IFolderArchiveExtractCallback(x) \ + x(AskOverwrite( \ const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize, \ const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize, \ - Int32 *answer) x; \ - STDMETHOD(PrepareOperation)(const wchar_t *name, Int32 isFolder, Int32 askExtractMode, const UInt64 *position) x; \ - STDMETHOD(MessageError)(const wchar_t *message) x; \ - STDMETHOD(SetOperationResult)(Int32 opRes, Int32 encrypted) x; \ + Int32 *answer)) \ + x(PrepareOperation(const wchar_t *name, Int32 isFolder, Int32 askExtractMode, const UInt64 *position)) \ + x(MessageError(const wchar_t *message)) \ + x(SetOperationResult(Int32 opRes, Int32 encrypted)) \ -DECL_INTERFACE_SUB(IFolderArchiveExtractCallback, IProgress, 0x01, 0x07) -{ - INTERFACE_IFolderArchiveExtractCallback(PURE) -}; +Z7_IFACE_CONSTR_FOLDERARC_SUB(IFolderArchiveExtractCallback, IProgress, 0x07) -#define INTERFACE_IFolderArchiveExtractCallback2(x) \ - STDMETHOD(ReportExtractResult)(Int32 opRes, Int32 encrypted, const wchar_t *name) x; \ +#define Z7_IFACEM_IFolderArchiveExtractCallback2(x) \ + x(ReportExtractResult(Int32 opRes, Int32 encrypted, const wchar_t *name)) \ -DECL_INTERFACE_SUB(IFolderArchiveExtractCallback2, IUnknown, 0x01, 0x08) -{ - INTERFACE_IFolderArchiveExtractCallback2(PURE) -}; +Z7_IFACE_CONSTR_FOLDERARC(IFolderArchiveExtractCallback2, 0x08) /* ---------- IExtractCallbackUI ---------- is implemented by @@ -70,45 +73,40 @@ is implemented by FileManager/ExtractCallback.h CExtractCallbackImp */ -#ifdef _NO_CRYPTO - #define INTERFACE_IExtractCallbackUI_Crypto(x) +#ifdef Z7_NO_CRYPTO + #define Z7_IFACEM_IExtractCallbackUI_Crypto(px) #else - #define INTERFACE_IExtractCallbackUI_Crypto(x) \ - virtual HRESULT SetPassword(const UString &password) x; + #define Z7_IFACEM_IExtractCallbackUI_Crypto(px) \ + virtual HRESULT SetPassword(const UString &password) px #endif -#define INTERFACE_IExtractCallbackUI(x) \ - virtual HRESULT BeforeOpen(const wchar_t *name, bool testMode) x; \ - virtual HRESULT OpenResult(const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result) x; \ - virtual HRESULT ThereAreNoFiles() x; \ - virtual HRESULT ExtractResult(HRESULT result) x; \ - INTERFACE_IExtractCallbackUI_Crypto(x) +#define Z7_IFACEN_IExtractCallbackUI(px) \ + virtual HRESULT BeforeOpen(const wchar_t *name, bool testMode) px \ + virtual HRESULT OpenResult(const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result) px \ + virtual HRESULT ThereAreNoFiles() px \ + virtual HRESULT ExtractResult(HRESULT result) px \ + Z7_IFACEM_IExtractCallbackUI_Crypto(px) -struct IExtractCallbackUI: IFolderArchiveExtractCallback -{ - INTERFACE_IExtractCallbackUI(PURE) -}; +// IExtractCallbackUI - is non-COM interface +// IFolderArchiveExtractCallback - is COM interface +// Z7_IFACE_DECL_PURE_(IExtractCallbackUI, IFolderArchiveExtractCallback) +Z7_IFACE_DECL_PURE(IExtractCallbackUI) -#define INTERFACE_IGetProp(x) \ - STDMETHOD(GetProp)(PROPID propID, PROPVARIANT *value) x; \ +#define Z7_IFACEM_IGetProp(x) \ + x(GetProp(PROPID propID, PROPVARIANT *value)) \ -DECL_INTERFACE_SUB(IGetProp, IUnknown, 0x01, 0x20) -{ - INTERFACE_IGetProp(PURE) -}; +Z7_IFACE_CONSTR_FOLDERARC(IGetProp, 0x20) -#define INTERFACE_IFolderExtractToStreamCallback(x) \ - STDMETHOD(UseExtractToStream)(Int32 *res) x; \ - STDMETHOD(GetStream7)(const wchar_t *name, Int32 isDir, ISequentialOutStream **outStream, Int32 askExtractMode, IGetProp *getProp) x; \ - STDMETHOD(PrepareOperation7)(Int32 askExtractMode) x; \ - STDMETHOD(SetOperationResult7)(Int32 resultEOperationResult, Int32 encrypted) x; \ +#define Z7_IFACEM_IFolderExtractToStreamCallback(x) \ + x(UseExtractToStream(Int32 *res)) \ + x(GetStream7(const wchar_t *name, Int32 isDir, ISequentialOutStream **outStream, Int32 askExtractMode, IGetProp *getProp)) \ + x(PrepareOperation7(Int32 askExtractMode)) \ + x(SetOperationResult8(Int32 resultEOperationResult, Int32 encrypted, UInt64 size)) \ -DECL_INTERFACE_SUB(IFolderExtractToStreamCallback, IUnknown, 0x01, 0x30) -{ - INTERFACE_IFolderExtractToStreamCallback(PURE) -}; +Z7_IFACE_CONSTR_FOLDERARC(IFolderExtractToStreamCallback, 0x31) +Z7_PURE_INTERFACES_END #endif diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/LoadCodecs.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/LoadCodecs.cpp index 5435499baa8..5a65bdcee83 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/LoadCodecs.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Common/LoadCodecs.cpp @@ -1,7 +1,7 @@ // LoadCodecs.cpp /* -EXTERNAL_CODECS +Z7_EXTERNAL_CODECS --------------- CCodecs::Load() tries to detect the directory with plugins. It stops the checking, if it can find any of the following items: @@ -22,7 +22,7 @@ EXTERNAL_CODECS EXPORT_CODECS ------------- - if (EXTERNAL_CODECS) is defined, then the code exports internal + if (Z7_EXTERNAL_CODECS) is defined, then the code exports internal codecs of client from CCodecs object to external plugins. 7-Zip doesn't use that feature. 7-Zip uses the scheme: - client application without internal plugins. @@ -33,38 +33,25 @@ EXPORT_CODECS #include "StdAfx.h" -#include "../../../../C/7zVersion.h" - #include "../../../Common/MyCom.h" #include "../../../Common/StringToInt.h" #include "../../../Common/StringConvert.h" +#include "../../../Windows/ErrorMsg.h" +#include "../../../Windows/FileIO.h" #include "../../../Windows/PropVariant.h" #include "LoadCodecs.h" -using namespace NWindows; - -#ifdef NEW_FOLDER_INTERFACE -#include "../../../Common/StringToInt.h" -#endif - #include "../../ICoder.h" #include "../../Common/RegisterArc.h" +#include "../../Common/RegisterCodec.h" -#ifdef EXTERNAL_CODECS - +#ifdef Z7_EXTERNAL_CODECS // #define EXPORT_CODECS - -#endif - -#ifdef NEW_FOLDER_INTERFACE -extern HINSTANCE g_hInstance; -#include "../../../Windows/ResourceString.h" -static const UINT kIconTypesResId = 100; #endif -#ifdef EXTERNAL_CODECS +#ifdef Z7_EXTERNAL_CODECS #include "../../../Windows/FileFind.h" #include "../../../Windows/DLL.h" @@ -74,6 +61,7 @@ static const UINT kIconTypesResId = 100; #include "../../../Windows/Registry.h" #endif +using namespace NWindows; using namespace NFile; @@ -81,19 +69,19 @@ using namespace NFile; #define kFormatsFolderName FTEXT("Formats") -static CFSTR kMainDll = - // #ifdef _WIN32 +static CFSTR const kMainDll = + #ifdef _WIN32 FTEXT("7z.dll"); - // #else - // FTEXT("7z.so"); - // #endif + #else + FTEXT("7z.so"); + #endif #ifdef _WIN32 -static LPCTSTR kRegistryPath = TEXT("Software") TEXT(STRING_PATH_SEPARATOR) TEXT("7-zip"); -static LPCWSTR kProgramPathValue = L"Path"; -static LPCWSTR kProgramPath2Value = L"Path" +static LPCTSTR const kRegistryPath = TEXT("Software") TEXT(STRING_PATH_SEPARATOR) TEXT("7-zip"); +static LPCWSTR const kProgramPathValue = L"Path"; +static LPCWSTR const kProgramPath2Value = L"Path" #ifdef _WIN64 L"64"; #else @@ -110,7 +98,7 @@ static bool ReadPathFromRegistry(HKEY baseKey, LPCWSTR value, FString &path) { path = us2fs(pathU); NName::NormalizeDirPathPrefix(path); - return NFind::DoesFileExist(path + kMainDll); + return NFind::DoesFileExist_Raw(path + kMainDll); } } return false; @@ -118,10 +106,10 @@ static bool ReadPathFromRegistry(HKEY baseKey, LPCWSTR value, FString &path) #endif // _WIN32 -#endif // EXTERNAL_CODECS +#endif // Z7_EXTERNAL_CODECS -static const unsigned kNumArcsMax = 64; +static const unsigned kNumArcsMax = 72; static unsigned g_NumArcs = 0; static const CArcInfo *g_Arcs[kNumArcsMax]; @@ -132,8 +120,10 @@ void RegisterArc(const CArcInfo *arcInfo) throw() g_Arcs[g_NumArcs] = arcInfo; g_NumArcs++; } + // else throw 1; } +/* static void SplitString(const UString &srcString, UStringVector &destStrings) { destStrings.Clear(); @@ -158,12 +148,13 @@ static void SplitString(const UString &srcString, UStringVector &destStrings) if (!s.IsEmpty()) destStrings.Add(s); } +*/ int CArcInfoEx::FindExtension(const UString &ext) const { FOR_VECTOR (i, Exts) if (ext.IsEqualTo_NoCase(Exts[i].Ext)) - return i; + return (int)i; return -1; } @@ -186,14 +177,14 @@ void CArcInfoEx::AddExts(const UString &ext, const UString &addExt) } } -#ifndef _SFX +#ifndef Z7_SFX static bool ParseSignatures(const Byte *data, unsigned size, CObjectVector<CByteBuffer> &signatures) { signatures.Clear(); - while (size > 0) + while (size != 0) { - unsigned len = *data++; + const unsigned len = *data++; size--; if (len > size) return false; @@ -204,17 +195,20 @@ static bool ParseSignatures(const Byte *data, unsigned size, CObjectVector<CByte return true; } -#endif // _SFX +#endif // Z7_SFX + +// #include <stdio.h> -#ifdef EXTERNAL_CODECS +#ifdef Z7_EXTERNAL_CODECS static FString GetBaseFolderPrefixFromRegistry() { FString moduleFolderPrefix = NDLL::GetModuleDirPrefix(); + #ifdef _WIN32 - if (!NFind::DoesFileExist(moduleFolderPrefix + kMainDll) && - !NFind::DoesDirExist(moduleFolderPrefix + kCodecsFolderName) && - !NFind::DoesDirExist(moduleFolderPrefix + kFormatsFolderName)) + if ( !NFind::DoesFileOrDirExist(moduleFolderPrefix + kMainDll) + && !NFind::DoesFileOrDirExist(moduleFolderPrefix + kCodecsFolderName) + && !NFind::DoesFileOrDirExist(moduleFolderPrefix + kFormatsFolderName)) { FString path; if (ReadPathFromRegistry(HKEY_CURRENT_USER, kProgramPath2Value, path)) return path; @@ -223,6 +217,8 @@ static FString GetBaseFolderPrefixFromRegistry() if (ReadPathFromRegistry(HKEY_LOCAL_MACHINE, kProgramPathValue, path)) return path; } #endif + + // printf("\nmoduleFolderPrefix = %s\n", (const char *)GetAnsiString(moduleFolderPrefix)); return moduleFolderPrefix; } @@ -232,50 +228,80 @@ static HRESULT GetCoderClass(Func_GetMethodProperty getMethodProperty, UInt32 in { NCOM::CPropVariant prop; isAssigned = false; - RINOK(getMethodProperty(index, propId, &prop)); + RINOK(getMethodProperty(index, propId, &prop)) if (prop.vt == VT_BSTR) { if (::SysStringByteLen(prop.bstrVal) != sizeof(GUID)) return E_FAIL; isAssigned = true; - clsId = *(const GUID *)prop.bstrVal; + clsId = *(const GUID *)(const void *)prop.bstrVal; } else if (prop.vt != VT_EMPTY) return E_FAIL; return S_OK; } + +static HRESULT GetMethodBoolProp(Func_GetMethodProperty getMethodProperty, UInt32 index, + PROPID propId, bool &resVal, bool &isAssigned) +{ + NCOM::CPropVariant prop; + resVal = false; + isAssigned = false; + RINOK(getMethodProperty(index, propId, &prop)) + if (prop.vt == VT_BOOL) + { + isAssigned = true; + resVal = VARIANT_BOOLToBool(prop.boolVal); + } + else if (prop.vt != VT_EMPTY) + return E_FAIL; + return S_OK; +} + +#if defined(__clang__) +#pragma GCC diagnostic ignored "-Wc++98-compat-pedantic" +#endif + +#define MY_GET_FUNC(dest, type, lib, func) \ + dest = Z7_GET_PROC_ADDRESS(type, lib.Get_HMODULE(), func); +// #define MY_GET_FUNC(dest, type, func) dest = (type)(func); + +#define MY_GET_FUNC_LOC(dest, type, lib, func) \ + type dest; MY_GET_FUNC(dest, type, lib, func) + HRESULT CCodecs::LoadCodecs() { CCodecLib &lib = Libs.Back(); - lib.CreateDecoder = (Func_CreateDecoder)lib.Lib.GetProc("CreateDecoder"); - lib.CreateEncoder = (Func_CreateEncoder)lib.Lib.GetProc("CreateEncoder"); - lib.GetMethodProperty = (Func_GetMethodProperty)lib.Lib.GetProc("GetMethodProperty"); + MY_GET_FUNC (lib.CreateDecoder, Func_CreateDecoder, lib.Lib, "CreateDecoder") + MY_GET_FUNC (lib.CreateEncoder, Func_CreateEncoder, lib.Lib, "CreateEncoder") + MY_GET_FUNC (lib.GetMethodProperty, Func_GetMethodProperty, lib.Lib, "GetMethodProperty") if (lib.GetMethodProperty) { UInt32 numMethods = 1; - Func_GetNumberOfMethods getNumberOfMethods = (Func_GetNumberOfMethods)lib.Lib.GetProc("GetNumberOfMethods"); + MY_GET_FUNC_LOC (getNumberOfMethods, Func_GetNumberOfMethods, lib.Lib, "GetNumberOfMethods") if (getNumberOfMethods) { - RINOK(getNumberOfMethods(&numMethods)); + RINOK(getNumberOfMethods(&numMethods)) } for (UInt32 i = 0; i < numMethods; i++) { CDllCodecInfo info; info.LibIndex = Libs.Size() - 1; info.CodecIndex = i; - RINOK(GetCoderClass(lib.GetMethodProperty, i, NMethodPropID::kEncoder, info.Encoder, info.EncoderIsAssigned)); - RINOK(GetCoderClass(lib.GetMethodProperty, i, NMethodPropID::kDecoder, info.Decoder, info.DecoderIsAssigned)); + RINOK(GetCoderClass(lib.GetMethodProperty, i, NMethodPropID::kEncoder, info.Encoder, info.EncoderIsAssigned)) + RINOK(GetCoderClass(lib.GetMethodProperty, i, NMethodPropID::kDecoder, info.Decoder, info.DecoderIsAssigned)) + RINOK(GetMethodBoolProp(lib.GetMethodProperty, i, NMethodPropID::kIsFilter, info.IsFilter, info.IsFilter_Assigned)) Codecs.Add(info); } } - Func_GetHashers getHashers = (Func_GetHashers)lib.Lib.GetProc("GetHashers"); + MY_GET_FUNC_LOC (getHashers, Func_GetHashers, lib.Lib, "GetHashers") if (getHashers) { - RINOK(getHashers(&lib.ComHashers)); + RINOK(getHashers(&lib.ComHashers)) if (lib.ComHashers) { UInt32 numMethods = lib.ComHashers->GetNumHashers(); @@ -298,7 +324,7 @@ static HRESULT GetProp( UInt32 index, PROPID propID, NCOM::CPropVariant &prop) { if (getProp2) - return getProp2(index, propID, &prop);; + return getProp2(index, propID, &prop); return getProp(propID, &prop); } @@ -309,7 +335,7 @@ static HRESULT GetProp_Bool( { res = false; NCOM::CPropVariant prop; - RINOK(GetProp(getProp, getProp2, index, propID, prop)); + RINOK(GetProp(getProp, getProp2, index, propID, prop)) if (prop.vt == VT_BOOL) res = VARIANT_BOOLToBool(prop.boolVal); else if (prop.vt != VT_EMPTY) @@ -325,7 +351,7 @@ static HRESULT GetProp_UInt32( res = 0; defined = false; NCOM::CPropVariant prop; - RINOK(GetProp(getProp, getProp2, index, propID, prop)); + RINOK(GetProp(getProp, getProp2, index, propID, prop)) if (prop.vt == VT_UI4) { res = prop.ulVal; @@ -343,7 +369,7 @@ static HRESULT GetProp_String( { res.Empty(); NCOM::CPropVariant prop; - RINOK(GetProp(getProp, getProp2, index, propID, prop)); + RINOK(GetProp(getProp, getProp2, index, propID, prop)) if (prop.vt == VT_BSTR) res.SetFromBstr(prop.bstrVal); else if (prop.vt != VT_EMPTY) @@ -358,7 +384,7 @@ static HRESULT GetProp_RawData( { bb.Free(); NCOM::CPropVariant prop; - RINOK(GetProp(getProp, getProp2, index, propID, prop)); + RINOK(GetProp(getProp, getProp2, index, propID, prop)) if (prop.vt == VT_BSTR) { UINT len = ::SysStringByteLen(prop.bstrVal); @@ -381,22 +407,22 @@ HRESULT CCodecs::LoadFormats() const NDLL::CLibrary &lib = Libs.Back().Lib; Func_GetHandlerProperty getProp = NULL; - Func_GetHandlerProperty2 getProp2 = (Func_GetHandlerProperty2)lib.GetProc("GetHandlerProperty2"); - Func_GetIsArc getIsArc = (Func_GetIsArc)lib.GetProc("GetIsArc"); + MY_GET_FUNC_LOC (getProp2, Func_GetHandlerProperty2, lib, "GetHandlerProperty2") + MY_GET_FUNC_LOC (getIsArc, Func_GetIsArc, lib, "GetIsArc") UInt32 numFormats = 1; if (getProp2) { - Func_GetNumberOfFormats getNumberOfFormats = (Func_GetNumberOfFormats)lib.GetProc("GetNumberOfFormats"); + MY_GET_FUNC_LOC (getNumberOfFormats, Func_GetNumberOfFormats, lib, "GetNumberOfFormats") if (getNumberOfFormats) { - RINOK(getNumberOfFormats(&numFormats)); + RINOK(getNumberOfFormats(&numFormats)) } } else { - getProp = (Func_GetHandlerProperty)lib.GetProc("GetHandlerProperty"); + MY_GET_FUNC (getProp, Func_GetHandlerProperty, lib, "GetHandlerProperty") if (!getProp) return S_OK; } @@ -404,10 +430,10 @@ HRESULT CCodecs::LoadFormats() for (UInt32 i = 0; i < numFormats; i++) { CArcInfoEx item; - item.LibIndex = Libs.Size() - 1; + item.LibIndex = (int)(Libs.Size() - 1); item.FormatIndex = i; - RINOK(GetProp_String(getProp, getProp2, i, NArchive::NHandlerPropID::kName, item.Name)); + RINOK(GetProp_String(getProp, getProp2, i, NArchive::NHandlerPropID::kName, item.Name)) { NCOM::CPropVariant prop; @@ -417,23 +443,23 @@ HRESULT CCodecs::LoadFormats() continue; if (::SysStringByteLen(prop.bstrVal) != sizeof(GUID)) return E_FAIL; - item.ClassID = *(const GUID *)prop.bstrVal; + item.ClassID = *(const GUID *)(const void *)prop.bstrVal; prop.Clear(); } UString ext, addExt; - RINOK(GetProp_String(getProp, getProp2, i, NArchive::NHandlerPropID::kExtension, ext)); - RINOK(GetProp_String(getProp, getProp2, i, NArchive::NHandlerPropID::kAddExtension, addExt)); + RINOK(GetProp_String(getProp, getProp2, i, NArchive::NHandlerPropID::kExtension, ext)) + RINOK(GetProp_String(getProp, getProp2, i, NArchive::NHandlerPropID::kAddExtension, addExt)) item.AddExts(ext, addExt); GetProp_Bool(getProp, getProp2, i, NArchive::NHandlerPropID::kUpdate, item.UpdateEnabled); bool flags_Defined = false; - RINOK(GetProp_UInt32(getProp, getProp2, i, NArchive::NHandlerPropID::kFlags, item.Flags, flags_Defined)); + RINOK(GetProp_UInt32(getProp, getProp2, i, NArchive::NHandlerPropID::kFlags, item.Flags, flags_Defined)) item.NewInterface = flags_Defined; if (!flags_Defined) // && item.UpdateEnabled { // support for DLL version before 9.31: - for (unsigned j = 0; j < ARRAY_SIZE(kArcFlagsPars); j += 2) + for (unsigned j = 0; j < Z7_ARRAY_SIZE(kArcFlagsPars); j += 2) { bool val = false; GetProp_Bool(getProp, getProp2, i, kArcFlagsPars[j], val); @@ -441,19 +467,24 @@ HRESULT CCodecs::LoadFormats() item.Flags |= kArcFlagsPars[j + 1]; } } + + { + bool defined = false; + RINOK(GetProp_UInt32(getProp, getProp2, i, NArchive::NHandlerPropID::kTimeFlags, item.TimeFlags, defined)) + } CByteBuffer sig; - RINOK(GetProp_RawData(getProp, getProp2, i, NArchive::NHandlerPropID::kSignature, sig)); + RINOK(GetProp_RawData(getProp, getProp2, i, NArchive::NHandlerPropID::kSignature, sig)) if (sig.Size() != 0) item.Signatures.Add(sig); else { - RINOK(GetProp_RawData(getProp, getProp2, i, NArchive::NHandlerPropID::kMultiSignature, sig)); + RINOK(GetProp_RawData(getProp, getProp2, i, NArchive::NHandlerPropID::kMultiSignature, sig)) ParseSignatures(sig, (unsigned)sig.Size(), item.Signatures); } bool signatureOffset_Defined; - RINOK(GetProp_UInt32(getProp, getProp2, i, NArchive::NHandlerPropID::kSignatureOffset, item.SignatureOffset, signatureOffset_Defined)); + RINOK(GetProp_UInt32(getProp, getProp2, i, NArchive::NHandlerPropID::kSignatureOffset, item.SignatureOffset, signatureOffset_Defined)) // bool version_Defined; // RINOK(GetProp_UInt32(getProp, getProp2, i, NArchive::NHandlerPropID::kVersion, item.Version, version_Defined)); @@ -466,86 +497,246 @@ HRESULT CCodecs::LoadFormats() return S_OK; } -#ifdef _7ZIP_LARGE_PAGES +#ifdef Z7_LARGE_PAGES extern "C" { extern SIZE_T g_LargePageSize; } #endif + +void CCodecs::AddLastError(const FString &path) +{ + const HRESULT res = GetLastError_noZero_HRESULT(); + CCodecError &error = Errors.AddNew(); + error.Path = path; + error.ErrorCode = res; +} + + +static bool IsSupportedDll(CCodecLib &lib) +{ + MY_GET_FUNC_LOC ( + f_GetModuleProp, + Func_GetModuleProp, lib.Lib, + "GetModuleProp") + /* p7zip and 7-Zip before v23 used virtual destructor in IUnknown, + if _WIN32 is not defined */ + UInt32 flags = + #ifdef _WIN32 + NModuleInterfaceType::k_IUnknown_VirtDestructor_No; + #else + NModuleInterfaceType::k_IUnknown_VirtDestructor_Yes; + #endif + if (f_GetModuleProp) + { + { + NCOM::CPropVariant prop; + if (f_GetModuleProp(NModulePropID::kInterfaceType, &prop) == S_OK) + { + if (prop.vt == VT_UI4) + flags = prop.ulVal; + else if (prop.vt != VT_EMPTY) + return false; + } + } + { + NCOM::CPropVariant prop; + if (f_GetModuleProp(NModulePropID::kVersion, &prop) == S_OK) + { + if (prop.vt == VT_UI4) + lib.Version = prop.ulVal; + } + } + } + if ( + flags + // (flags & NModuleFlags::kMask) + != NModuleInterfaceType::k_IUnknown_VirtDestructor_ThisModule) + return false; + return true; +} + + HRESULT CCodecs::LoadDll(const FString &dllPath, bool needCheckDll, bool *loadedOK) { if (loadedOK) *loadedOK = false; + // needCheckDll = 1; + + #ifdef _WIN32 if (needCheckDll) { NDLL::CLibrary lib; if (!lib.LoadEx(dllPath, LOAD_LIBRARY_AS_DATAFILE)) + { + /* if is not win32 + // %1 is not a valid Win32 application. + // #define ERROR_BAD_EXE_FORMAT 193L + */ + // return GetLastError_noZero_HRESULT(); + const DWORD lastError = GetLastError(); + if (lastError != ERROR_BAD_EXE_FORMAT) + { + CCodecError &error = Errors.AddNew(); + error.Path = dllPath; + error.Message = "cannot load file as datafile library"; + error.ErrorCode = HRESULT_FROM_WIN32(lastError); + } return S_OK; + } } + #else + UNUSED_VAR(needCheckDll) + #endif Libs.AddNew(); CCodecLib &lib = Libs.Back(); lib.Path = dllPath; bool used = false; - HRESULT res = S_OK; + // HRESULT res = S_OK; - if (lib.Lib.Load(dllPath)) + if (lib.Lib.Load(dllPath)) + { + if (!IsSupportedDll(lib)) + { + CCodecError &error = Errors.AddNew(); + error.Path = dllPath; + error.Message = "the module is not compatible with program"; + } + else { if (loadedOK) *loadedOK = true; + /* #ifdef NEW_FOLDER_INTERFACE lib.LoadIcons(); #endif + */ - #ifdef _7ZIP_LARGE_PAGES + /* + { + MY_GET_FUNC_LOC (_libStartup, Func_libStartup, lib.Lib, "LibStartup") + if (_libStartup) + { + HRESULT res = _libStartup(); + if (res != 0) + { + CCodecError &error = Errors.AddNew(); + error.Path = dllPath; + error.ErrorCode = res; + } + } + } + */ + + #ifdef Z7_LARGE_PAGES if (g_LargePageSize != 0) { - Func_SetLargePageMode setLargePageMode = (Func_SetLargePageMode)lib.Lib.GetProc("SetLargePageMode"); + MY_GET_FUNC_LOC (setLargePageMode, Func_SetLargePageMode, lib.Lib, "SetLargePageMode") if (setLargePageMode) setLargePageMode(); } #endif - if (CaseSensitiveChange) + if (CaseSensitive_Change) { - Func_SetCaseSensitive setCaseSensitive = (Func_SetCaseSensitive)lib.Lib.GetProc("SetCaseSensitive"); + MY_GET_FUNC_LOC (setCaseSensitive, Func_SetCaseSensitive, lib.Lib, "SetCaseSensitive") if (setCaseSensitive) setCaseSensitive(CaseSensitive ? 1 : 0); } - lib.CreateObject = (Func_CreateObject)lib.Lib.GetProc("CreateObject"); - if (lib.CreateObject) + /* + { + MY_GET_FUNC_LOC (setClientVersion, Func_SetClientVersion, lib.Lib, "SetClientVersion") + if (setClientVersion) + { + // const UInt32 kVersion = (MY_VER_MAJOR << 16) | MY_VER_MINOR; + setClientVersion(g_ClientVersion); + } + } + */ + + + MY_GET_FUNC (lib.CreateObject, Func_CreateObject, lib.Lib, "CreateObject") { unsigned startSize = Codecs.Size() + Hashers.Size(); - res = LoadCodecs(); - used = (startSize != Codecs.Size() + Hashers.Size()); - if (res == S_OK) + HRESULT res = LoadCodecs(); + if (startSize != Codecs.Size() + Hashers.Size()) + used = true; + if (res == S_OK && lib.CreateObject) { startSize = Formats.Size(); res = LoadFormats(); if (startSize != Formats.Size()) used = true; } + if (res != S_OK) + { + CCodecError &error = Errors.AddNew(); + error.Path = dllPath; + error.ErrorCode = res; + } + } + // plugins can use non-7-zip dlls, so we silently ignore non7zip DLLs + /* + if (!used) + { + CCodecError &error = Errors.AddNew(); + error.Path = dllPath; + error.Message = "no 7-Zip code"; } + */ + } + } + else + { + AddLastError(dllPath); } if (!used) Libs.DeleteBack(); - return res; + return S_OK; } -HRESULT CCodecs::LoadDllsFromFolder(const FString &folderPrefix) +HRESULT CCodecs::LoadDllsFromFolder(const FString &folderPath) { - NFile::NFind::CEnumerator enumerator(folderPrefix + FCHAR_ANY_MASK); - NFile::NFind::CFileInfo fi; - while (enumerator.Next(fi)) + if (!NFile::NFind::DoesDirExist_FollowLink(folderPath)) + // if (!NFile::NFind::DoesDirExist(folderPath)) { + // AddLastError(folderPath); + return S_OK; + } + + FString folderPrefix = folderPath; + folderPrefix.Add_PathSepar(); + + NFile::NFind::CEnumerator enumerator; + enumerator.SetDirPrefix(folderPrefix); + NFile::NFind::CDirEntry fi; + for (;;) + { + bool found; + if (!enumerator.Next(fi, found)) + { + // it can be wrong Symbolic link to folder here + AddLastError(folderPath); + break; + // return GetLastError_noZero_HRESULT(); + } + if (!found) + break; + #ifdef _WIN32 if (fi.IsDir()) continue; - RINOK(LoadDll(folderPrefix + fi.Name, true)); + #else + if (enumerator.DirEntry_IsDir(fi, true)) // followLink + continue; + #endif + + RINOK(LoadDll(folderPrefix + fi.Name, true)) } return S_OK; } @@ -573,18 +764,21 @@ void CCodecs::CloseLibs() // OutputDebugStringA("~CloseLibs end"); } -#endif // EXTERNAL_CODECS +#endif // Z7_EXTERNAL_CODECS HRESULT CCodecs::Load() { + /* #ifdef NEW_FOLDER_INTERFACE InternalIcons.LoadIcons(g_hInstance); #endif + */ Formats.Clear(); - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS + Errors.Clear(); MainDll_ErrorPath.Empty(); Codecs.Clear(); Hashers.Clear(); @@ -595,7 +789,7 @@ HRESULT CCodecs::Load() const CArcInfo &arc = *g_Arcs[i]; CArcInfoEx item; - item.Name.SetFromAscii(arc.Name); + item.Name = arc.Name; item.CreateInArchive = arc.CreateInArchive; item.IsArcFunc = arc.IsArc; item.Flags = arc.Flags; @@ -603,13 +797,13 @@ HRESULT CCodecs::Load() { UString e, ae; if (arc.Ext) - e.SetFromAscii(arc.Ext); + e = arc.Ext; if (arc.AddExt) - ae.SetFromAscii(arc.AddExt); + ae = arc.AddExt; item.AddExts(e, ae); } - #ifndef _SFX + #ifndef Z7_SFX item.CreateOutArchive = arc.CreateOutArchive; item.UpdateEnabled = (arc.CreateOutArchive != NULL); @@ -620,23 +814,28 @@ HRESULT CCodecs::Load() if (arc.IsMultiSignature()) ParseSignatures(arc.Signature, arc.SignatureSize, item.Signatures); else - item.Signatures.AddNew().CopyFrom(arc.Signature, arc.SignatureSize); + { + if (arc.SignatureSize != 0) // 21.04 + item.Signatures.AddNew().CopyFrom(arc.Signature, arc.SignatureSize); + } #endif Formats.Add(item); } - #ifdef EXTERNAL_CODECS + // printf("\nLoad codecs \n"); + + #ifdef Z7_EXTERNAL_CODECS const FString baseFolder = GetBaseFolderPrefixFromRegistry(); { bool loadedOK; - RINOK(LoadDll(baseFolder + kMainDll, false, &loadedOK)); + RINOK(LoadDll(baseFolder + kMainDll, false, &loadedOK)) if (!loadedOK) MainDll_ErrorPath = kMainDll; } - RINOK(LoadDllsFromFolder(baseFolder + kCodecsFolderName FSTRING_PATH_SEPARATOR)); - RINOK(LoadDllsFromFolder(baseFolder + kFormatsFolderName FSTRING_PATH_SEPARATOR)); + RINOK(LoadDllsFromFolder(baseFolder + kCodecsFolderName)) + RINOK(LoadDllsFromFolder(baseFolder + kFormatsFolderName)) NeedSetLibCodecs = true; @@ -659,27 +858,29 @@ HRESULT CCodecs::Load() FOR_VECTOR(i, Libs) { CCodecLib &lib = Libs[i]; - lib.SetCodecs = (Func_SetCodecs)lib.Lib.GetProc("SetCodecs"); + MY_GET_FUNC (lib.SetCodecs, Func_SetCodecs, lib.Lib, "SetCodecs") if (lib.SetCodecs) { - RINOK(lib.SetCodecs(this)); + RINOK(lib.SetCodecs(this)) } } } #endif + // we sort Formats to get fixed order of Formats after compilation. + Formats.Sort(); return S_OK; } -#ifndef _SFX +#ifndef Z7_SFX int CCodecs::FindFormatForArchiveName(const UString &arcPath) const { int dotPos = arcPath.ReverseFind_Dot(); if (dotPos <= arcPath.ReverseFind_PathSepar()) return -1; - const UString ext = arcPath.Ptr(dotPos + 1); + const UString ext = arcPath.Ptr((unsigned)(dotPos + 1)); if (ext.IsEmpty()) return -1; if (ext.IsEqualTo_Ascii_NoCase("exe")) @@ -692,7 +893,7 @@ int CCodecs::FindFormatForArchiveName(const UString &arcPath) const continue; */ if (arc.FindExtension(ext) >= 0) - return i; + return (int)i; } return -1; } @@ -703,7 +904,7 @@ int CCodecs::FindFormatForExtension(const UString &ext) const return -1; FOR_VECTOR (i, Formats) if (Formats[i].FindExtension(ext) >= 0) - return i; + return (int)i; return -1; } @@ -711,7 +912,7 @@ int CCodecs::FindFormatForArchiveType(const UString &arcType) const { FOR_VECTOR (i, Formats) if (Formats[i].Name.IsEqualTo_NoCase(arcType)) - return i; + return (int)i; return -1; } @@ -722,8 +923,8 @@ bool CCodecs::FindFormatForArchiveType(const UString &arcType, CIntVector &forma { int pos2 = arcType.Find(L'.', pos); if (pos2 < 0) - pos2 = arcType.Len(); - const UString name = arcType.Mid(pos, pos2 - pos); + pos2 = (int)arcType.Len(); + const UString name = arcType.Mid(pos, (unsigned)pos2 - pos); if (name.IsEmpty()) return false; int index = FindFormatForArchiveType(name); @@ -733,65 +934,15 @@ bool CCodecs::FindFormatForArchiveType(const UString &arcType, CIntVector &forma return false; } formatIndices.Add(index); - pos = pos2 + 1; + pos = (unsigned)pos2 + 1; } return true; } -#endif // _SFX - - -#ifdef NEW_FOLDER_INTERFACE - -void CCodecIcons::LoadIcons(HMODULE m) -{ - UString iconTypes; - MyLoadString(m, kIconTypesResId, iconTypes); - UStringVector pairs; - SplitString(iconTypes, pairs); - FOR_VECTOR (i, pairs) - { - const UString &s = pairs[i]; - int pos = s.Find(L':'); - CIconPair iconPair; - iconPair.IconIndex = -1; - if (pos < 0) - pos = s.Len(); - else - { - UString num = s.Ptr(pos + 1); - if (!num.IsEmpty()) - { - const wchar_t *end; - iconPair.IconIndex = ConvertStringToUInt32(num, &end); - if (*end != 0) - continue; - } - } - iconPair.Ext = s.Left(pos); - IconPairs.Add(iconPair); - } -} - -bool CCodecIcons::FindIconIndex(const UString &ext, int &iconIndex) const -{ - iconIndex = -1; - FOR_VECTOR (i, IconPairs) - { - const CIconPair &pair = IconPairs[i]; - if (ext.IsEqualTo_NoCase(pair.Ext)) - { - iconIndex = pair.IconIndex; - return true; - } - } - return false; -} +#endif // Z7_SFX -#endif // NEW_FOLDER_INTERFACE - -#ifdef EXTERNAL_CODECS +#ifdef Z7_EXTERNAL_CODECS // #define EXPORT_CODECS @@ -815,24 +966,24 @@ STDAPI GetHasherProp(UInt32 codecIndex, PROPID propID, PROPVARIANT *value); #endif // EXPORT_CODECS -STDMETHODIMP CCodecs::GetNumMethods(UInt32 *numMethods) +Z7_COM7F_IMF(CCodecs::GetNumMethods(UInt32 *numMethods)) { *numMethods = NUM_EXPORT_CODECS - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS + Codecs.Size() #endif ; return S_OK; } -STDMETHODIMP CCodecs::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CCodecs::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { #ifdef EXPORT_CODECS if (index < g_NumCodecs) return GetMethodProperty(index, propID, value); #endif - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS const CDllCodecInfo &ci = Codecs[index - NUM_EXPORT_CODECS]; if (propID == NMethodPropID::kDecoderIsAssigned || @@ -845,6 +996,15 @@ STDMETHODIMP CCodecs::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *valu prop.Detach(value); return S_OK; } + + if (propID == NMethodPropID::kIsFilter && ci.IsFilter_Assigned) + { + NCOM::CPropVariant prop; + prop = (bool)ci.IsFilter; + prop.Detach(value); + return S_OK; + } + const CCodecLib &lib = Libs[ci.LibIndex]; return lib.GetMethodProperty(ci.CodecIndex, propID, value); #else @@ -852,21 +1012,22 @@ STDMETHODIMP CCodecs::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *valu #endif } -STDMETHODIMP CCodecs::CreateDecoder(UInt32 index, const GUID *iid, void **coder) +Z7_COM7F_IMF(CCodecs::CreateDecoder(UInt32 index, const GUID *iid, void **coder)) { #ifdef EXPORT_CODECS if (index < g_NumCodecs) return CreateDecoder(index, iid, coder); #endif - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS const CDllCodecInfo &ci = Codecs[index - NUM_EXPORT_CODECS]; if (ci.DecoderIsAssigned) { const CCodecLib &lib = Libs[ci.LibIndex]; if (lib.CreateDecoder) return lib.CreateDecoder(ci.CodecIndex, iid, (void **)coder); - return lib.CreateObject(&ci.Decoder, iid, (void **)coder); + if (lib.CreateObject) + return lib.CreateObject(&ci.Decoder, iid, (void **)coder); } return S_OK; #else @@ -874,21 +1035,22 @@ STDMETHODIMP CCodecs::CreateDecoder(UInt32 index, const GUID *iid, void **coder) #endif } -STDMETHODIMP CCodecs::CreateEncoder(UInt32 index, const GUID *iid, void **coder) +Z7_COM7F_IMF(CCodecs::CreateEncoder(UInt32 index, const GUID *iid, void **coder)) { #ifdef EXPORT_CODECS if (index < g_NumCodecs) return CreateEncoder(index, iid, coder); #endif - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS const CDllCodecInfo &ci = Codecs[index - NUM_EXPORT_CODECS]; if (ci.EncoderIsAssigned) { const CCodecLib &lib = Libs[ci.LibIndex]; if (lib.CreateEncoder) return lib.CreateEncoder(ci.CodecIndex, iid, (void **)coder); - return lib.CreateObject(&ci.Encoder, iid, (void **)coder); + if (lib.CreateObject) + return lib.CreateObject(&ci.Encoder, iid, (void **)coder); } return S_OK; #else @@ -897,23 +1059,23 @@ STDMETHODIMP CCodecs::CreateEncoder(UInt32 index, const GUID *iid, void **coder) } -STDMETHODIMP_(UInt32) CCodecs::GetNumHashers() +Z7_COM7F_IMF2(UInt32, CCodecs::GetNumHashers()) { return NUM_EXPORT_HASHERS - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS + Hashers.Size() #endif ; } -STDMETHODIMP CCodecs::GetHasherProp(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CCodecs::GetHasherProp(UInt32 index, PROPID propID, PROPVARIANT *value)) { #ifdef EXPORT_CODECS if (index < g_NumHashers) return ::GetHasherProp(index, propID, value); #endif - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS const CDllHasherInfo &ci = Hashers[index - NUM_EXPORT_HASHERS]; return Libs[ci.LibIndex].ComHashers->GetHasherProp(ci.HasherIndex, propID, value); #else @@ -921,13 +1083,13 @@ STDMETHODIMP CCodecs::GetHasherProp(UInt32 index, PROPID propID, PROPVARIANT *va #endif } -STDMETHODIMP CCodecs::CreateHasher(UInt32 index, IHasher **hasher) +Z7_COM7F_IMF(CCodecs::CreateHasher(UInt32 index, IHasher **hasher)) { #ifdef EXPORT_CODECS if (index < g_NumHashers) return CreateHasher(index, hasher); #endif - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS const CDllHasherInfo &ci = Hashers[index - NUM_EXPORT_HASHERS]; return Libs[ci.LibIndex].ComHashers->CreateHasher(ci.HasherIndex, hasher); #else @@ -942,9 +1104,9 @@ int CCodecs::GetCodec_LibIndex(UInt32 index) const return -1; #endif - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS const CDllCodecInfo &ci = Codecs[index - NUM_EXPORT_CODECS]; - return ci.LibIndex; + return (int)ci.LibIndex; #else return -1; #endif @@ -957,9 +1119,9 @@ int CCodecs::GetHasherLibIndex(UInt32 index) return -1; #endif - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS const CDllHasherInfo &ci = Hashers[index - NUM_EXPORT_HASHERS]; - return ci.LibIndex; + return (int)ci.LibIndex; #else return -1; #endif @@ -980,13 +1142,14 @@ bool CCodecs::GetCodec_DecoderIsAssigned(UInt32 index) const } #endif - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS return Codecs[index - NUM_EXPORT_CODECS].DecoderIsAssigned; #else return false; #endif } + bool CCodecs::GetCodec_EncoderIsAssigned(UInt32 index) const { #ifdef EXPORT_CODECS @@ -1002,17 +1165,50 @@ bool CCodecs::GetCodec_EncoderIsAssigned(UInt32 index) const } #endif - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS return Codecs[index - NUM_EXPORT_CODECS].EncoderIsAssigned; #else return false; #endif } + +bool CCodecs::GetCodec_IsFilter(UInt32 index, bool &isAssigned) const +{ + isAssigned = false; + #ifdef EXPORT_CODECS + if (index < g_NumCodecs) + { + NCOM::CPropVariant prop; + if (GetProperty(index, NMethodPropID::kIsFilter, &prop) == S_OK) + { + if (prop.vt == VT_BOOL) + { + isAssigned = true; + return VARIANT_BOOLToBool(prop.boolVal); + } + } + return false; + } + #endif + + #ifdef Z7_EXTERNAL_CODECS + { + const CDllCodecInfo &c = Codecs[index - NUM_EXPORT_CODECS]; + isAssigned = c.IsFilter_Assigned; + return c.IsFilter; + } + #else + return false; + #endif +} + + UInt32 CCodecs::GetCodec_NumStreams(UInt32 index) { NCOM::CPropVariant prop; - RINOK(GetProperty(index, NMethodPropID::kPackStreams, &prop)); + if (GetProperty(index, NMethodPropID::kPackStreams, &prop) != S_OK) + return 0; if (prop.vt == VT_UI4) return (UInt32)prop.ulVal; if (prop.vt == VT_EMPTY) @@ -1023,7 +1219,7 @@ UInt32 CCodecs::GetCodec_NumStreams(UInt32 index) HRESULT CCodecs::GetCodec_Id(UInt32 index, UInt64 &id) { NCOM::CPropVariant prop; - RINOK(GetProperty(index, NMethodPropID::kID, &prop)); + RINOK(GetProperty(index, NMethodPropID::kID, &prop)) if (prop.vt != VT_UI8) return E_INVALIDARG; id = prop.uhVal.QuadPart; @@ -1063,10 +1259,75 @@ AString CCodecs::GetHasherName(UInt32 index) UInt32 CCodecs::GetHasherDigestSize(UInt32 index) { NCOM::CPropVariant prop; - RINOK(GetHasherProp(index, NMethodPropID::kDigestSize, &prop)); + if (GetHasherProp(index, NMethodPropID::kDigestSize, &prop) != S_OK) + return 0; if (prop.vt != VT_UI4) return 0; return prop.ulVal; } -#endif // EXTERNAL_CODECS +void CCodecs::GetCodecsErrorMessage(UString &s) +{ + s.Empty(); + FOR_VECTOR (i, Errors) + { + const CCodecError &ce = Errors[i]; + s += "Codec Load Error: "; + s += fs2us(ce.Path); + if (ce.ErrorCode != 0) + { + s += " : "; + s += NWindows::NError::MyFormatMessage(ce.ErrorCode); + } + if (!ce.Message.IsEmpty()) + { + s += " : "; + s += ce.Message; + } + s.Add_LF(); + } +} + +#endif // Z7_EXTERNAL_CODECS + +#ifndef Z7_SFX + +extern unsigned g_NumCodecs; +extern const CCodecInfo *g_Codecs[]; + +void CCodecs::Get_CodecsInfoUser_Vector(CObjectVector<CCodecInfoUser> &v) +{ + v.Clear(); + { + for (unsigned i = 0; i < g_NumCodecs; i++) + { + const CCodecInfo &cod = *g_Codecs[i]; + CCodecInfoUser &u = v.AddNew(); + u.EncoderIsAssigned = (cod.CreateEncoder != NULL); + u.DecoderIsAssigned = (cod.CreateDecoder != NULL); + u.IsFilter_Assigned = true; + u.IsFilter = cod.IsFilter; + u.NumStreams = cod.NumStreams; + u.Name = cod.Name; + } + } + + + #ifdef Z7_EXTERNAL_CODECS + { + UInt32 numMethods; + if (GetNumMethods(&numMethods) == S_OK) + for (UInt32 j = 0; j < numMethods; j++) + { + CCodecInfoUser &u = v.AddNew(); + u.EncoderIsAssigned = GetCodec_EncoderIsAssigned(j); + u.DecoderIsAssigned = GetCodec_DecoderIsAssigned(j); + u.IsFilter = GetCodec_IsFilter(j, u.IsFilter_Assigned); + u.NumStreams = GetCodec_NumStreams(j); + u.Name = GetCodec_Name(j); + } + } + #endif +} + +#endif diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/LoadCodecs.h b/3rdparty/lzma/CPP/7zip/UI/Common/LoadCodecs.h index ac9eeac71dd..a81bb5c74a9 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/LoadCodecs.h +++ b/3rdparty/lzma/CPP/7zip/UI/Common/LoadCodecs.h @@ -1,7 +1,7 @@ // LoadCodecs.h -#ifndef __LOAD_CODECS_H -#define __LOAD_CODECS_H +#ifndef ZIP7_INC_LOAD_CODECS_H +#define ZIP7_INC_LOAD_CODECS_H /* Client application uses LoadCodecs.* to load plugins to @@ -10,26 +10,26 @@ CCodecs object, that contains 3 lists of plugins: 2) Codecs - external codecs 3) Hashers - external hashers -EXTERNAL_CODECS +Z7_EXTERNAL_CODECS --------------- - if EXTERNAL_CODECS is defined, then the code tries to load external + if Z7_EXTERNAL_CODECS is defined, then the code tries to load external plugins from DLL files (shared libraries). There are two types of executables in 7-Zip: 1) Executable that uses external plugins must be compiled - with EXTERNAL_CODECS defined: + with Z7_EXTERNAL_CODECS defined: - 7z.exe, 7zG.exe, 7zFM.exe - Note: EXTERNAL_CODECS is used also in CPP/7zip/Common/CreateCoder.h + Note: Z7_EXTERNAL_CODECS is used also in CPP/7zip/Common/CreateCoder.h that code is used in plugin module (7z.dll). - 2) Standalone modules are compiled without EXTERNAL_CODECS: + 2) Standalone modules are compiled without Z7_EXTERNAL_CODECS: - SFX modules: 7z.sfx, 7zCon.sfx - standalone versions of console 7-Zip: 7za.exe, 7zr.exe - if EXTERNAL_CODECS is defined, CCodecs class implements interfaces: + if Z7_EXTERNAL_CODECS is defined, CCodecs class implements interfaces: - ICompressCodecsInfo : for Codecs - IHashers : for Hashers @@ -51,7 +51,7 @@ EXTERNAL_CODECS #include "../../../Common/MyString.h" #include "../../../Common/ComTry.h" -#ifdef EXTERNAL_CODECS +#ifdef Z7_EXTERNAL_CODECS #include "../../../Windows/DLL.h" #endif @@ -60,7 +60,7 @@ EXTERNAL_CODECS #include "../../Archive/IArchive.h" -#ifdef EXTERNAL_CODECS +#ifdef Z7_EXTERNAL_CODECS struct CDllCodecInfo { @@ -68,6 +68,8 @@ struct CDllCodecInfo UInt32 CodecIndex; bool EncoderIsAssigned; bool DecoderIsAssigned; + bool IsFilter; + bool IsFilter_Assigned; CLSID Encoder; CLSID Decoder; }; @@ -94,6 +96,7 @@ struct CArcExtInfo struct CArcInfoEx { UInt32 Flags; + UInt32 TimeFlags; Func_CreateInArchive CreateInArchive; Func_IsArc IsArcFunc; @@ -101,29 +104,48 @@ struct CArcInfoEx UString Name; CObjectVector<CArcExtInfo> Exts; - #ifndef _SFX + #ifndef Z7_SFX Func_CreateOutArchive CreateOutArchive; bool UpdateEnabled; bool NewInterface; // UInt32 Version; UInt32 SignatureOffset; CObjectVector<CByteBuffer> Signatures; + /* #ifdef NEW_FOLDER_INTERFACE UStringVector AssociateExts; #endif + */ #endif - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS int LibIndex; UInt32 FormatIndex; CLSID ClassID; #endif + int Compare(const CArcInfoEx &a) const + { + const int res = Name.Compare(a.Name); + if (res != 0) + return res; + #ifdef Z7_EXTERNAL_CODECS + return MyCompare(LibIndex, a.LibIndex); + #else + return 0; + #endif + /* + if (LibIndex < a.LibIndex) return -1; + if (LibIndex > a.LibIndex) return 1; + return 0; + */ + } + bool Flags_KeepName() const { return (Flags & NArcInfoFlags::kKeepName) != 0; } bool Flags_FindSignature() const { return (Flags & NArcInfoFlags::kFindSignature) != 0; } bool Flags_AltStreams() const { return (Flags & NArcInfoFlags::kAltStreams) != 0; } - bool Flags_NtSecure() const { return (Flags & NArcInfoFlags::kNtSecure) != 0; } + bool Flags_NtSecurity() const { return (Flags & NArcInfoFlags::kNtSecure) != 0; } bool Flags_SymLinks() const { return (Flags & NArcInfoFlags::kSymLinks) != 0; } bool Flags_HardLinks() const { return (Flags & NArcInfoFlags::kHardLinks) != 0; } @@ -132,7 +154,30 @@ struct CArcInfoEx bool Flags_BackwardOpen() const { return (Flags & NArcInfoFlags::kBackwardOpen) != 0; } bool Flags_PreArc() const { return (Flags & NArcInfoFlags::kPreArc) != 0; } bool Flags_PureStartOpen() const { return (Flags & NArcInfoFlags::kPureStartOpen) != 0; } - + bool Flags_ByExtOnlyOpen() const { return (Flags & NArcInfoFlags::kByExtOnlyOpen) != 0; } + bool Flags_HashHandler() const { return (Flags & NArcInfoFlags::kHashHandler) != 0; } + + bool Flags_CTime() const { return (Flags & NArcInfoFlags::kCTime) != 0; } + bool Flags_ATime() const { return (Flags & NArcInfoFlags::kATime) != 0; } + bool Flags_MTime() const { return (Flags & NArcInfoFlags::kMTime) != 0; } + + bool Flags_CTime_Default() const { return (Flags & NArcInfoFlags::kCTime_Default) != 0; } + bool Flags_ATime_Default() const { return (Flags & NArcInfoFlags::kATime_Default) != 0; } + bool Flags_MTime_Default() const { return (Flags & NArcInfoFlags::kMTime_Default) != 0; } + + UInt32 Get_TimePrecFlags() const + { + return (TimeFlags >> NArcInfoTimeFlags::kTime_Prec_Mask_bit_index) & + (((UInt32)1 << NArcInfoTimeFlags::kTime_Prec_Mask_num_bits) - 1); + } + + UInt32 Get_DefaultTimePrec() const + { + return (TimeFlags >> NArcInfoTimeFlags::kTime_Prec_Default_bit_index) & + (((UInt32)1 << NArcInfoTimeFlags::kTime_Prec_Default_num_bits) - 1); + } + + UString GetMainExt() const { if (Exts.IsEmpty()) @@ -141,6 +186,16 @@ struct CArcInfoEx } int FindExtension(const UString &ext) const; + bool Is_7z() const { return Name.IsEqualTo_Ascii_NoCase("7z"); } + bool Is_Split() const { return Name.IsEqualTo_Ascii_NoCase("Split"); } + bool Is_Xz() const { return Name.IsEqualTo_Ascii_NoCase("xz"); } + bool Is_BZip2() const { return Name.IsEqualTo_Ascii_NoCase("bzip2"); } + bool Is_GZip() const { return Name.IsEqualTo_Ascii_NoCase("gzip"); } + bool Is_Tar() const { return Name.IsEqualTo_Ascii_NoCase("tar"); } + bool Is_Zip() const { return Name.IsEqualTo_Ascii_NoCase("zip"); } + bool Is_Rar() const { return Name.IsEqualTo_Ascii_NoCase("rar"); } + bool Is_Zstd() const { return Name.IsEqualTo_Ascii_NoCase("zstd"); } + /* UString GetAllExtensions() const { @@ -148,7 +203,7 @@ struct CArcInfoEx for (int i = 0; i < Exts.Size(); i++) { if (i > 0) - s += ' '; + s.Add_Space(); s += Exts[i].Ext; } return s; @@ -157,49 +212,29 @@ struct CArcInfoEx void AddExts(const UString &ext, const UString &addExt); - bool IsSplit() const { return StringsAreEqualNoCase_Ascii(Name, "Split"); } - // bool IsRar() const { return StringsAreEqualNoCase_Ascii(Name, "Rar"); } CArcInfoEx(): Flags(0), + TimeFlags(0), CreateInArchive(NULL), IsArcFunc(NULL) - #ifndef _SFX + #ifndef Z7_SFX , CreateOutArchive(NULL) , UpdateEnabled(false) , NewInterface(false) // , Version(0) , SignatureOffset(0) #endif - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS , LibIndex(-1) #endif {} }; -#ifdef NEW_FOLDER_INTERFACE - -struct CCodecIcons -{ - struct CIconPair - { - UString Ext; - int IconIndex; - }; - CObjectVector<CIconPair> IconPairs; - - void LoadIcons(HMODULE m); - bool FindIconIndex(const UString &ext, int &iconIndex) const; -}; -#endif - -#ifdef EXTERNAL_CODECS +#ifdef Z7_EXTERNAL_CODECS struct CCodecLib - #ifdef NEW_FOLDER_INTERFACE - : public CCodecIcons - #endif { NWindows::NDLL::CLibrary Lib; FString Path; @@ -211,25 +246,53 @@ struct CCodecLib Func_SetCodecs SetCodecs; CMyComPtr<IHashers> ComHashers; + + UInt32 Version; + /* #ifdef NEW_FOLDER_INTERFACE - void LoadIcons() { CCodecIcons::LoadIcons((HMODULE)Lib); } + CCodecIcons CodecIcons; + void LoadIcons() { CodecIcons.LoadIcons((HMODULE)Lib); } #endif + */ CCodecLib(): CreateObject(NULL), GetMethodProperty(NULL), CreateDecoder(NULL), CreateEncoder(NULL), - SetCodecs(NULL) + SetCodecs(NULL), + Version(0) {} }; #endif +struct CCodecError +{ + FString Path; + HRESULT ErrorCode; + AString Message; + CCodecError(): ErrorCode(0) {} +}; + + +struct CCodecInfoUser +{ + // unsigned LibIndex; + // UInt32 CodecIndex; + // UInt64 id; + bool EncoderIsAssigned; + bool DecoderIsAssigned; + bool IsFilter; + bool IsFilter_Assigned; + UInt32 NumStreams; + AString Name; +}; -class CCodecs: - #ifdef EXTERNAL_CODECS + +class CCodecs Z7_final: + #ifdef Z7_EXTERNAL_CODECS public ICompressCodecsInfo, public IHashers, #else @@ -237,18 +300,26 @@ class CCodecs: #endif public CMyUnknownImp { - CLASS_NO_COPY(CCodecs); +#ifdef Z7_EXTERNAL_CODECS + Z7_IFACES_IMP_UNK_2(ICompressCodecsInfo, IHashers) +#else + Z7_COM_UNKNOWN_IMP_0 +#endif // Z7_EXTERNAL_CODECS + + Z7_CLASS_NO_COPY(CCodecs) public: - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS CObjectVector<CCodecLib> Libs; FString MainDll_ErrorPath; - + CObjectVector<CCodecError> Errors; + + void AddLastError(const FString &path); void CloseLibs(); class CReleaser { - CLASS_NO_COPY(CReleaser); + Z7_CLASS_NO_COPY(CReleaser) /* CCodecsReleaser object releases CCodecs links. 1) CCodecs is COM object that is deleted when all links to that object will be released/ @@ -272,30 +343,32 @@ public: HRESULT CreateArchiveHandler(const CArcInfoEx &ai, bool outHandler, void **archive) const { - return Libs[ai.LibIndex].CreateObject(&ai.ClassID, outHandler ? &IID_IOutArchive : &IID_IInArchive, (void **)archive); + return Libs[(unsigned)ai.LibIndex].CreateObject(&ai.ClassID, outHandler ? &IID_IOutArchive : &IID_IInArchive, (void **)archive); } #endif + /* #ifdef NEW_FOLDER_INTERFACE CCodecIcons InternalIcons; #endif + */ CObjectVector<CArcInfoEx> Formats; - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS CRecordVector<CDllCodecInfo> Codecs; CRecordVector<CDllHasherInfo> Hashers; #endif - bool CaseSensitiveChange; + bool CaseSensitive_Change; bool CaseSensitive; CCodecs(): - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS NeedSetLibCodecs(true), #endif - CaseSensitiveChange(false), + CaseSensitive_Change(false), CaseSensitive(false) {} @@ -306,43 +379,24 @@ public: const wchar_t *GetFormatNamePtr(int formatIndex) const { - return formatIndex < 0 ? L"#" : (const wchar_t *)Formats[formatIndex].Name; + return formatIndex < 0 ? L"#" : (const wchar_t *)Formats[(unsigned)formatIndex].Name; } HRESULT Load(); - - #ifndef _SFX + + #ifndef Z7_SFX int FindFormatForArchiveName(const UString &arcPath) const; int FindFormatForExtension(const UString &ext) const; int FindFormatForArchiveType(const UString &arcType) const; bool FindFormatForArchiveType(const UString &arcType, CIntVector &formatIndices) const; #endif - #ifdef EXTERNAL_CODECS - - MY_UNKNOWN_IMP2(ICompressCodecsInfo, IHashers) - - STDMETHOD(GetNumMethods)(UInt32 *numMethods); - STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(CreateDecoder)(UInt32 index, const GUID *iid, void **coder); - STDMETHOD(CreateEncoder)(UInt32 index, const GUID *iid, void **coder); - - STDMETHOD_(UInt32, GetNumHashers)(); - STDMETHOD(GetHasherProp)(UInt32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(CreateHasher)(UInt32 index, IHasher **hasher); - - #else - - MY_UNKNOWN_IMP - - #endif // EXTERNAL_CODECS - - - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS int GetCodec_LibIndex(UInt32 index) const; bool GetCodec_DecoderIsAssigned(UInt32 index) const; bool GetCodec_EncoderIsAssigned(UInt32 index) const; + bool GetCodec_IsFilter(UInt32 index, bool &isAssigned) const; UInt32 GetCodec_NumStreams(UInt32 index); HRESULT GetCodec_Id(UInt32 index, UInt64 &id); AString GetCodec_Name(UInt32 index); @@ -352,12 +406,14 @@ public: AString GetHasherName(UInt32 index); UInt32 GetHasherDigestSize(UInt32 index); + void GetCodecsErrorMessage(UString &s); + #endif HRESULT CreateInArchive(unsigned formatIndex, CMyComPtr<IInArchive> &archive) const { const CArcInfoEx &ai = Formats[formatIndex]; - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS if (ai.LibIndex < 0) #endif { @@ -366,17 +422,17 @@ public: return S_OK; COM_TRY_END } - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS return CreateArchiveHandler(ai, false, (void **)&archive); #endif } - #ifndef _SFX + #ifndef Z7_SFX HRESULT CreateOutArchive(unsigned formatIndex, CMyComPtr<IOutArchive> &archive) const { const CArcInfoEx &ai = Formats[formatIndex]; - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS if (ai.LibIndex < 0) #endif { @@ -386,7 +442,7 @@ public: COM_TRY_END } - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS return CreateArchiveHandler(ai, true, (void **)&archive); #endif } @@ -399,26 +455,28 @@ public: if (!arc.UpdateEnabled) continue; if (arc.Name.IsEqualTo_NoCase(name)) - return i; + return (int)i; } return -1; } - #endif // _SFX + void Get_CodecsInfoUser_Vector(CObjectVector<CCodecInfoUser> &v); + + #endif // Z7_SFX }; -#ifdef EXTERNAL_CODECS +#ifdef Z7_EXTERNAL_CODECS #define CREATE_CODECS_OBJECT \ CCodecs *codecs = new CCodecs; \ - CExternalCodecs __externalCodecs; \ - __externalCodecs.GetCodecs = codecs; \ - __externalCodecs.GetHashers = codecs; \ + CExternalCodecs _externalCodecs; \ + _externalCodecs.GetCodecs = codecs; \ + _externalCodecs.GetHashers = codecs; \ CCodecs::CReleaser codecsReleaser; \ codecsReleaser.Set(codecs); #else #define CREATE_CODECS_OBJECT \ CCodecs *codecs = new CCodecs; \ - CMyComPtr<IUnknown> __codecsRef = codecs; + CMyComPtr<IUnknown> _codecsRef = codecs; #endif - + #endif diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/OpenArchive.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/OpenArchive.cpp index bf3b982e44e..a501b86d4b1 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/OpenArchive.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Common/OpenArchive.cpp @@ -14,6 +14,7 @@ #include "../../../Common/IntToString.h" #include "../../../Common/StringConvert.h" #include "../../../Common/StringToInt.h" +#include "../../../Common/UTFConvert.h" #include "../../../Common/Wildcard.h" #include "../../../Windows/FileDir.h" @@ -28,15 +29,17 @@ #include "DefaultName.h" #include "OpenArchive.h" -#ifndef _SFX +#ifndef Z7_SFX #include "SetProperties.h" #endif +#ifndef Z7_SFX #ifdef SHOW_DEBUG_INFO #define PRF(x) x #else #define PRF(x) #endif +#endif // increase it, if you need to support larger SFX stubs static const UInt64 kMaxCheckStartPosition = 1 << 23; @@ -64,7 +67,7 @@ Open: - open FAIL: Try to open with all other types from offset 0 only. If some open type is OK and physical archive size is uequal or larger - than file size, then return that archive with warning that can not be open as [extension type]. + than file size, then return that archive with warning that cannot be open as [extension type]. If extension was EXE, it will try to open as unknown_extension case - file has unknown extension (like a.hhh) It tries to open via parser code. @@ -92,7 +95,7 @@ Open: using namespace NWindows; /* -#ifdef _SFX +#ifdef Z7_SFX #define OPEN_PROPS_PARAM #else #define OPEN_PROPS_PARAM , props @@ -108,7 +111,7 @@ CArc::~CArc() } */ -#ifndef _SFX +#ifndef Z7_SFX namespace NArchive { namespace NParser { @@ -141,14 +144,14 @@ struct CParseItem bool LenIsUnknown; CParseItem(): - LenIsUnknown(false), + // OkSize(0), FileTime_Defined(false), UnpackSize_Defined(false), - NumSubFiles_Defined(false), NumSubDirs_Defined(false), + NumSubFiles_Defined(false), IsSelfExe(false), - IsNotArcType(false) - // OkSize(0) + IsNotArcType(false), + LenIsUnknown(false) {} /* @@ -169,23 +172,14 @@ struct CParseItem } }; -class CHandler: - public IInArchive, - public IInArchiveGetStream, - public CMyUnknownImp -{ +Z7_CLASS_IMP_CHandler_IInArchive_1( + IInArchiveGetStream +) public: CObjectVector<CParseItem> _items; UInt64 _maxEndOffset; CMyComPtr<IInStream> _stream; - MY_UNKNOWN_IMP2( - IInArchive, - IInArchiveGetStream) - - INTERFACE_IInArchive(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); - UInt64 GetLastEnd() const { if (_items.IsEmpty()) @@ -206,23 +200,25 @@ int CHandler::FindInsertPos(const CParseItem &item) const unsigned left = 0, right = _items.Size(); while (left != right) { - unsigned mid = (left + right) / 2; - const CParseItem & midItem = _items[mid]; + const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); + const CParseItem &midItem = _items[mid]; if (item.Offset < midItem.Offset) right = mid; else if (item.Offset > midItem.Offset) left = mid + 1; else if (item.Size < midItem.Size) right = mid; + /* else if (item.Size > midItem.Size) left = mid + 1; + */ else { left = mid + 1; // return -1; } } - return left; + return (int)left; } void CHandler::AddUnknownItem(UInt64 next) @@ -257,10 +253,10 @@ void CHandler::AddUnknownItem(UInt64 next) void CHandler::AddItem(const CParseItem &item) { AddUnknownItem(item.Offset); - int pos = FindInsertPos(item); - if (pos >= 0) + const int pos = FindInsertPos(item); + if (pos != -1) { - _items.Insert(pos, item); + _items.Insert((unsigned)pos, item); UInt64 next = item.Offset + item.Size; if (_maxEndOffset < next) _maxEndOffset = next; @@ -295,7 +291,7 @@ static const Byte kProps[] = IMP_IInArchive_Props IMP_IInArchive_ArcProps_NO -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback * /* openArchiveCallback */) +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback * /* openArchiveCallback */)) { COM_TRY_BEGIN { @@ -306,20 +302,20 @@ STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallb COM_TRY_END } -STDMETHODIMP CHandler::Close() +Z7_COM7F_IMF(CHandler::Close()) { _items.Clear(); _stream.Release(); return S_OK; } -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) { *numItems = _items.Size(); return S_OK; } -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN NCOM::CPropVariant prop; @@ -330,17 +326,17 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val { case kpidPath: { - wchar_t sz[32]; + char sz[32]; ConvertUInt32ToString(index + 1, sz); - UString s = sz; + UString s(sz); if (!item.Name.IsEmpty()) { - s += L'.'; + s.Add_Dot(); s += item.Name; } if (!item.Extension.IsEmpty()) { - s += L'.'; + s.Add_Dot(); s += item.Extension; } prop = s; break; @@ -360,12 +356,12 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val COM_TRY_END } -HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) { COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); if (allFilesMode) numItems = _items.Size(); if (_stream && numItems == 0) @@ -396,35 +392,35 @@ HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems, { lps->InSize = totalSize; lps->OutSize = totalSize; - RINOK(lps->SetCur()); + RINOK(lps->SetCur()) CMyComPtr<ISequentialOutStream> realOutStream; - Int32 askMode = testMode ? + const Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; - Int32 index = allFilesMode ? i : indices[i]; + const UInt32 index = allFilesMode ? i : indices[i]; const CParseItem &item = _items[index]; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) UInt64 unpackSize = item.Size; totalSize += unpackSize; bool skipMode = false; if (!testMode && !realOutStream) continue; - RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->PrepareOperation(askMode)) outStreamSpec->SetStream(realOutStream); realOutStream.Release(); outStreamSpec->Init(skipMode ? 0 : unpackSize, true); Int32 opRes = NExtract::NOperationResult::kOK; - RINOK(_stream->Seek(item.Offset, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(_stream, item.Offset)) streamSpec->Init(unpackSize); - RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)); + RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)) if (outStreamSpec->GetRem() != 0) opRes = NExtract::NOperationResult::kDataError; outStreamSpec->ReleaseStream(); - RINOK(extractCallback->SetOperationResult(opRes)); + RINOK(extractCallback->SetOperationResult(opRes)) } return S_OK; @@ -433,7 +429,7 @@ HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems, } -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) { COM_TRY_BEGIN const CParseItem &item = _items[index]; @@ -449,7 +445,7 @@ HRESULT Archive_GetItemBoolProp(IInArchive *arc, UInt32 index, PROPID propID, bo { NCOM::CPropVariant prop; result = false; - RINOK(arc->GetProperty(index, propID, &prop)); + RINOK(arc->GetProperty(index, propID, &prop)) if (prop.vt == VT_BOOL) result = VARIANT_BOOLToBool(prop.boolVal); else if (prop.vt != VT_EMPTY) @@ -477,11 +473,11 @@ HRESULT Archive_IsItem_Deleted(IInArchive *arc, UInt32 index, bool &result) thro return Archive_GetItemBoolProp(arc, index, kpidIsDeleted, result); } -static HRESULT Archive_GetArcBoolProp(IInArchive *arc, PROPID propid, bool &result) throw() +static HRESULT Archive_GetArcProp_Bool(IInArchive *arc, PROPID propid, bool &result) throw() { NCOM::CPropVariant prop; result = false; - RINOK(arc->GetArchiveProperty(propid, &prop)); + RINOK(arc->GetArchiveProperty(propid, &prop)) if (prop.vt == VT_BOOL) result = VARIANT_BOOLToBool(prop.boolVal); else if (prop.vt != VT_EMPTY) @@ -493,16 +489,17 @@ static HRESULT Archive_GetArcProp_UInt(IInArchive *arc, PROPID propid, UInt64 &r { defined = false; NCOM::CPropVariant prop; - RINOK(arc->GetArchiveProperty(propid, &prop)); + RINOK(arc->GetArchiveProperty(propid, &prop)) switch (prop.vt) { - case VT_UI4: result = prop.ulVal; defined = true; break; - case VT_I4: result = (Int64)prop.lVal; defined = true; break; - case VT_UI8: result = (UInt64)prop.uhVal.QuadPart; defined = true; break; - case VT_I8: result = (UInt64)prop.hVal.QuadPart; defined = true; break; - case VT_EMPTY: break; + case VT_UI4: result = prop.ulVal; break; + case VT_I4: result = (UInt64)(Int64)prop.lVal; break; + case VT_UI8: result = (UInt64)prop.uhVal.QuadPart; break; + case VT_I8: result = (UInt64)prop.hVal.QuadPart; break; + case VT_EMPTY: return S_OK; default: return E_FAIL; } + defined = true; return S_OK; } @@ -510,22 +507,23 @@ static HRESULT Archive_GetArcProp_Int(IInArchive *arc, PROPID propid, Int64 &res { defined = false; NCOM::CPropVariant prop; - RINOK(arc->GetArchiveProperty(propid, &prop)); + RINOK(arc->GetArchiveProperty(propid, &prop)) switch (prop.vt) { - case VT_UI4: result = prop.ulVal; defined = true; break; - case VT_I4: result = prop.lVal; defined = true; break; - case VT_UI8: result = (Int64)prop.uhVal.QuadPart; defined = true; break; - case VT_I8: result = (Int64)prop.hVal.QuadPart; defined = true; break; - case VT_EMPTY: break; + case VT_UI4: result = prop.ulVal; break; + case VT_I4: result = prop.lVal; break; + case VT_UI8: result = (Int64)prop.uhVal.QuadPart; break; + case VT_I8: result = (Int64)prop.hVal.QuadPart; break; + case VT_EMPTY: return S_OK; default: return E_FAIL; } + defined = true; return S_OK; } -#ifndef _SFX +#ifndef Z7_SFX -HRESULT CArc::GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &parts) const +HRESULT CArc::GetItem_PathToParent(UInt32 index, UInt32 parent, UStringVector &parts) const { if (!GetRawProps) return E_FAIL; @@ -543,14 +541,14 @@ HRESULT CArc::GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &pa const void *p; UInt32 size; UInt32 propType; - RINOK(GetRawProps->GetRawProp(curIndex, kpidName, &p, &size, &propType)); + RINOK(GetRawProps->GetRawProp(curIndex, kpidName, &p, &size, &propType)) if (p && propType == PROP_DATA_TYPE_wchar_t_PTR_Z_LE) s = (const wchar_t *)p; else #endif { NCOM::CPropVariant prop; - RINOK(Archive->GetProperty(curIndex, kpidName, &prop)); + RINOK(Archive->GetProperty(curIndex, kpidName, &prop)) if (prop.vt == VT_BSTR && prop.bstrVal) s.SetFromBstr(prop.bstrVal); else if (prop.vt == VT_EMPTY) @@ -561,8 +559,10 @@ HRESULT CArc::GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &pa UInt32 curParent = (UInt32)(Int32)-1; UInt32 parentType = 0; - RINOK(GetRawProps->GetParent(curIndex, &curParent, &parentType)); + RINOK(GetRawProps->GetParent(curIndex, &curParent, &parentType)) + // 18.06: fixed : we don't want to split name to parts + /* if (parentType != NParentType::kAltStream) { for (;;) @@ -576,6 +576,7 @@ HRESULT CArc::GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &pa s.DeleteFrom(pos); } } + */ parts.Insert(0, s); @@ -583,7 +584,7 @@ HRESULT CArc::GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &pa { { UString &s2 = parts[parts.Size() - 2]; - s2 += L':'; + s2 += ':'; s2 += parts.Back(); } parts.DeleteBack(); @@ -604,7 +605,9 @@ HRESULT CArc::GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &pa #endif -HRESULT CArc::GetItemPath(UInt32 index, UString &result) const + + +HRESULT CArc::GetItem_Path(UInt32 index, UString &result) const { #ifdef MY_CPU_LE if (GetRawProps) @@ -618,19 +621,42 @@ HRESULT CArc::GetItemPath(UInt32 index, UString &result) const propType == NPropDataType::kUtf16z) { unsigned len = size / 2 - 1; + // (len) doesn't include null terminator + + /* + #if WCHAR_MAX > 0xffff + len = (unsigned)Utf16LE__Get_Num_WCHARs(p, len); + + wchar_t *s = result.GetBuf(len); + wchar_t *sEnd = Utf16LE__To_WCHARs_Sep(p, len, s); + if (s + len != sEnd) return E_FAIL; + *sEnd = 0; + + #else + */ + wchar_t *s = result.GetBuf(len); for (unsigned i = 0; i < len; i++) { wchar_t c = GetUi16(p); p = (const void *)((const Byte *)p + 2); + #if WCHAR_PATH_SEPARATOR != L'/' if (c == L'/') c = WCHAR_PATH_SEPARATOR; + else if (c == L'\\') + c = WCHAR_IN_FILE_NAME_BACKSLASH_REPLACEMENT; // WSL scheme #endif + *s++ = c; } *s = 0; + + // #endif + result.ReleaseBuf_SetLen(len); + + Convert_UnicodeEsc16_To_UnicodeEscHigh(result); if (len != 0) return S_OK; } @@ -707,7 +733,7 @@ HRESULT CArc::GetItemPath(UInt32 index, UString &result) const { NCOM::CPropVariant prop; - RINOK(Archive->GetProperty(index, kpidPath, &prop)); + RINOK(Archive->GetProperty(index, kpidPath, &prop)) if (prop.vt == VT_BSTR && prop.bstrVal) result.SetFromBstr(prop.bstrVal); else if (prop.vt == VT_EMPTY) @@ -717,23 +743,25 @@ HRESULT CArc::GetItemPath(UInt32 index, UString &result) const } if (result.IsEmpty()) - return GetDefaultItemPath(index, result); + return GetItem_DefaultPath(index, result); + + Convert_UnicodeEsc16_To_UnicodeEscHigh(result); return S_OK; } -HRESULT CArc::GetDefaultItemPath(UInt32 index, UString &result) const +HRESULT CArc::GetItem_DefaultPath(UInt32 index, UString &result) const { result.Empty(); bool isDir; - RINOK(Archive_IsItem_Dir(Archive, index, isDir)); + RINOK(Archive_IsItem_Dir(Archive, index, isDir)) if (!isDir) { result = DefaultName; NCOM::CPropVariant prop; - RINOK(Archive->GetProperty(index, kpidExtension, &prop)); + RINOK(Archive->GetProperty(index, kpidExtension, &prop)) if (prop.vt == VT_BSTR) { - result += L'.'; + result.Add_Dot(); result += prop.bstrVal; } else if (prop.vt != VT_EMPTY) @@ -742,13 +770,13 @@ HRESULT CArc::GetDefaultItemPath(UInt32 index, UString &result) const return S_OK; } -HRESULT CArc::GetItemPath2(UInt32 index, UString &result) const +HRESULT CArc::GetItem_Path2(UInt32 index, UString &result) const { - RINOK(GetItemPath(index, result)); + RINOK(GetItem_Path(index, result)) if (Ask_Deleted) { bool isDeleted = false; - RINOK(Archive_IsItem_Deleted(Archive, index, isDeleted)); + RINOK(Archive_IsItem_Deleted(Archive, index, isDeleted)) if (isDeleted) result.Insert(0, L"[DELETED]" WSTRING_PATH_SEPARATOR); } @@ -769,7 +797,7 @@ int FindAltStreamColon_in_Path(const wchar_t *path) if (c == ':') { if (colonPos < 0) - colonPos = i; + colonPos = (int)i; continue; } if (c == WCHAR_PATH_SEPARATOR) @@ -793,12 +821,12 @@ HRESULT CArc::GetItem(UInt32 index, CReadArcItem &item) const item.PathParts.Clear(); - RINOK(Archive_IsItem_Dir(Archive, index, item.IsDir)); + RINOK(Archive_IsItem_Dir(Archive, index, item.IsDir)) item.MainIsDir = item.IsDir; - RINOK(GetItemPath2(index, item.Path)); + RINOK(GetItem_Path2(index, item.Path)) - #ifndef _SFX + #ifndef Z7_SFX UInt32 mainIndex = index; #endif @@ -807,7 +835,7 @@ HRESULT CArc::GetItem(UInt32 index, CReadArcItem &item) const item.MainPath = item.Path; if (Ask_AltStream) { - RINOK(Archive_IsItem_AltStream(Archive, index, item.IsAltStream)); + RINOK(Archive_IsItem_AltStream(Archive, index, item.IsAltStream)) } bool needFindAltStream = false; @@ -819,11 +847,11 @@ HRESULT CArc::GetItem(UInt32 index, CReadArcItem &item) const { UInt32 parentType = 0; UInt32 parentIndex; - RINOK(GetRawProps->GetParent(index, &parentIndex, &parentType)); + RINOK(GetRawProps->GetParent(index, &parentIndex, &parentType)) if (parentType == NParentType::kAltStream) { NCOM::CPropVariant prop; - RINOK(Archive->GetProperty(index, kpidName, &prop)); + RINOK(Archive->GetProperty(index, kpidName, &prop)) if (prop.vt == VT_BSTR && prop.bstrVal) item.AltStreamName.SetFromBstr(prop.bstrVal); else if (prop.vt != VT_EMPTY) @@ -848,8 +876,8 @@ HRESULT CArc::GetItem(UInt32 index, CReadArcItem &item) const } else { - RINOK(GetItemPath2(parentIndex, item.MainPath)); - RINOK(Archive_IsItem_Dir(Archive, parentIndex, item.MainIsDir)); + RINOK(GetItem_Path2(parentIndex, item.MainPath)) + RINOK(Archive_IsItem_Dir(Archive, parentIndex, item.MainIsDir)) } } } @@ -857,13 +885,13 @@ HRESULT CArc::GetItem(UInt32 index, CReadArcItem &item) const if (item.WriteToAltStreamIfColon || needFindAltStream) { - /* Good handler must support GetRawProps::GetParent for alt streams./ + /* Good handler must support GetRawProps::GetParent for alt streams. So the following code currently is not used */ int colon = FindAltStreamColon_in_Path(item.Path); if (colon >= 0) { - item.MainPath.DeleteFrom(colon); - item.AltStreamName = item.Path.Ptr(colon + 1); + item.MainPath.DeleteFrom((unsigned)colon); + item.AltStreamName = item.Path.Ptr((unsigned)(colon + 1)); item.MainIsDir = (colon == 0 || IsPathSepar(item.Path[(unsigned)colon - 1])); item.IsAltStream = true; } @@ -871,10 +899,10 @@ HRESULT CArc::GetItem(UInt32 index, CReadArcItem &item) const #endif - #ifndef _SFX + #ifndef Z7_SFX if (item._use_baseParentFolder_mode) { - RINOK(GetItemPathToParent(mainIndex, item._baseParentFolder, item.PathParts)); + RINOK(GetItem_PathToParent(mainIndex, (unsigned)item._baseParentFolder, item.PathParts)) #ifdef SUPPORT_ALT_STREAMS if ((item.WriteToAltStreamIfColon || needFindAltStream) && !item.PathParts.IsEmpty()) @@ -885,10 +913,10 @@ HRESULT CArc::GetItem(UInt32 index, CReadArcItem &item) const colon = FindAltStreamColon_in_Path(s); if (colon >= 0) { - item.AltStreamName = s.Ptr(colon + 1); + item.AltStreamName = s.Ptr((unsigned)(colon + 1)); item.MainIsDir = (colon == 0 || IsPathSepar(s[(unsigned)colon - 1])); item.IsAltStream = true; - s.DeleteFrom(colon); + s.DeleteFrom((unsigned)colon); } } if (colon == 0) @@ -910,14 +938,14 @@ HRESULT CArc::GetItem(UInt32 index, CReadArcItem &item) const return S_OK; } -#ifndef _SFX +#ifndef Z7_SFX static HRESULT Archive_GetItem_Size(IInArchive *archive, UInt32 index, UInt64 &size, bool &defined) { NCOM::CPropVariant prop; defined = false; size = 0; - RINOK(archive->GetProperty(index, kpidSize, &prop)); + RINOK(archive->GetProperty(index, kpidSize, &prop)) switch (prop.vt) { case VT_UI1: size = prop.bVal; break; @@ -933,12 +961,12 @@ static HRESULT Archive_GetItem_Size(IInArchive *archive, UInt32 index, UInt64 &s #endif -HRESULT CArc::GetItemSize(UInt32 index, UInt64 &size, bool &defined) const +HRESULT CArc::GetItem_Size(UInt32 index, UInt64 &size, bool &defined) const { NCOM::CPropVariant prop; defined = false; size = 0; - RINOK(Archive->GetProperty(index, kpidSize, &prop)); + RINOK(Archive->GetProperty(index, kpidSize, &prop)) switch (prop.vt) { case VT_UI1: size = prop.bVal; break; @@ -952,28 +980,56 @@ HRESULT CArc::GetItemSize(UInt32 index, UInt64 &size, bool &defined) const return S_OK; } -HRESULT CArc::GetItemMTime(UInt32 index, FILETIME &ft, bool &defined) const +HRESULT CArc::GetItem_MTime(UInt32 index, CArcTime &at) const { + at.Clear(); NCOM::CPropVariant prop; - defined = false; - ft.dwHighDateTime = ft.dwLowDateTime = 0; - RINOK(Archive->GetProperty(index, kpidMTime, &prop)); + RINOK(Archive->GetProperty(index, kpidMTime, &prop)) + if (prop.vt == VT_FILETIME) { - ft = prop.filetime; - defined = true; + /* + // for debug + if (FILETIME_IsZero(prop.at) && MTime.Def) + { + at = MTime; + return S_OK; + } + */ + at.Set_From_Prop(prop); + if (at.Prec == 0) + { + // (at.Prec == 0) before version 22. + // so kpidTimeType is required for that code + prop.Clear(); + RINOK(Archive->GetProperty(index, kpidTimeType, &prop)) + if (prop.vt == VT_UI4) + { + UInt32 val = prop.ulVal; + if (val == NFileTimeType::kWindows) + val = k_PropVar_TimePrec_100ns; + /* + else if (val > k_PropVar_TimePrec_1ns) + { + val = k_PropVar_TimePrec_100ns; + // val = k_PropVar_TimePrec_1ns; + // return E_FAIL; // for debug + } + */ + at.Prec = (UInt16)val; + } + } + return S_OK; } - else if (prop.vt != VT_EMPTY) + + if (prop.vt != VT_EMPTY) return E_FAIL; - else if (MTimeDefined) - { - ft = MTime; - defined = true; - } + if (MTime.Def) + at = MTime; return S_OK; } -#ifndef _SFX +#ifndef Z7_SFX static inline bool TestSignature(const Byte *p1, const Byte *p2, size_t size) { @@ -983,52 +1039,52 @@ static inline bool TestSignature(const Byte *p1, const Byte *p2, size_t size) return true; } + static void MakeCheckOrder(CCodecs *codecs, CIntVector &orderIndices, unsigned numTypes, CIntVector &orderIndices2, const Byte *data, size_t dataSize) { for (unsigned i = 0; i < numTypes; i++) { - int index = orderIndices[i]; + const int index = orderIndices[i]; if (index < 0) continue; - const CArcInfoEx &ai = codecs->Formats[index]; - if (ai.SignatureOffset != 0) - { - orderIndices2.Add(index); - orderIndices[i] = -1; - continue; - } - - const CObjectVector<CByteBuffer> &sigs = ai.Signatures; - FOR_VECTOR (k, sigs) + const CArcInfoEx &ai = codecs->Formats[(unsigned)index]; + if (ai.SignatureOffset == 0) { - const CByteBuffer &sig = sigs[k]; - if (sig.Size() == 0 && dataSize == 0 || - sig.Size() != 0 && sig.Size() <= dataSize && - TestSignature(data, sig, sig.Size())) + if (ai.Signatures.IsEmpty()) { - orderIndices2.Add(index); - orderIndices[i] = -1; - break; + if (dataSize != 0) // 21.04: no Signature means Empty Signature + continue; + } + else + { + unsigned k; + const CObjectVector<CByteBuffer> &sigs = ai.Signatures; + for (k = 0; k < sigs.Size(); k++) + { + const CByteBuffer &sig = sigs[k]; + if (sig.Size() <= dataSize && TestSignature(data, sig, sig.Size())) + break; + } + if (k == sigs.Size()) + continue; } } + orderIndices2.Add(index); + orderIndices[i] = -1; } } -#endif - #ifdef UNDER_CE static const unsigned kNumHashBytes = 1; - #define HASH_VAL(buf, pos) ((buf)[pos]) + #define HASH_VAL(buf) ((buf)[0]) #else static const unsigned kNumHashBytes = 2; - #define HASH_VAL(buf, pos) ((buf)[pos] | ((UInt32)(buf)[pos + 1] << 8)) + // #define HASH_VAL(buf) ((buf)[0] | ((UInt32)(buf)[1] << 8)) + #define HASH_VAL(buf) GetUi16(buf) #endif - -#ifndef _SFX - static bool IsExeExt(const UString &ext) { return ext.IsEqualTo_Ascii_NoCase("exe"); @@ -1056,7 +1112,7 @@ static bool IsPreArcFormat(const CArcInfoEx &ai) { if (ai.Flags_PreArc()) return true; - return IsNameFromList(ai.Name, k_PreArcFormats, ARRAY_SIZE(k_PreArcFormats)); + return IsNameFromList(ai.Name, k_PreArcFormats, Z7_ARRAY_SIZE(k_PreArcFormats)); } static const char * const k_Formats_with_simple_signuature[] = @@ -1078,44 +1134,46 @@ static bool IsNewStyleSignature(const CArcInfoEx &ai) // if (ai.Version >= 0x91F) if (ai.NewInterface) return true; - return IsNameFromList(ai.Name, k_Formats_with_simple_signuature, ARRAY_SIZE(k_Formats_with_simple_signuature)); + return IsNameFromList(ai.Name, k_Formats_with_simple_signuature, Z7_ARRAY_SIZE(k_Formats_with_simple_signuature)); } -class CArchiveOpenCallback_Offset: + + +class CArchiveOpenCallback_Offset Z7_final: public IArchiveOpenCallback, public IArchiveOpenVolumeCallback, - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO public ICryptoGetTextPassword, - #endif + #endif public CMyUnknownImp { + Z7_COM_QI_BEGIN2(IArchiveOpenCallback) + Z7_COM_QI_ENTRY(IArchiveOpenVolumeCallback) + #ifndef Z7_NO_CRYPTO + Z7_COM_QI_ENTRY(ICryptoGetTextPassword) + #endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(IArchiveOpenCallback) + Z7_IFACE_COM7_IMP(IArchiveOpenVolumeCallback) + #ifndef Z7_NO_CRYPTO + Z7_IFACE_COM7_IMP(ICryptoGetTextPassword) + #endif + public: CMyComPtr<IArchiveOpenCallback> Callback; CMyComPtr<IArchiveOpenVolumeCallback> OpenVolumeCallback; UInt64 Files; UInt64 Offset; - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO CMyComPtr<ICryptoGetTextPassword> GetTextPassword; #endif - - MY_QUERYINTERFACE_BEGIN2(IArchiveOpenCallback) - MY_QUERYINTERFACE_ENTRY(IArchiveOpenVolumeCallback) - #ifndef _NO_CRYPTO - MY_QUERYINTERFACE_ENTRY(ICryptoGetTextPassword) - #endif - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - INTERFACE_IArchiveOpenCallback(;) - INTERFACE_IArchiveOpenVolumeCallback(;) - #ifndef _NO_CRYPTO - STDMETHOD(CryptoGetTextPassword)(BSTR *password); - #endif }; -#ifndef _NO_CRYPTO -STDMETHODIMP CArchiveOpenCallback_Offset::CryptoGetTextPassword(BSTR *password) +#ifndef Z7_NO_CRYPTO +Z7_COM7F_IMF(CArchiveOpenCallback_Offset::CryptoGetTextPassword(BSTR *password)) { COM_TRY_BEGIN if (GetTextPassword) @@ -1125,12 +1183,12 @@ STDMETHODIMP CArchiveOpenCallback_Offset::CryptoGetTextPassword(BSTR *password) } #endif -STDMETHODIMP CArchiveOpenCallback_Offset::SetTotal(const UInt64 *, const UInt64 *) +Z7_COM7F_IMF(CArchiveOpenCallback_Offset::SetTotal(const UInt64 *, const UInt64 *)) { return S_OK; } -STDMETHODIMP CArchiveOpenCallback_Offset::SetCompleted(const UInt64 *, const UInt64 *bytes) +Z7_COM7F_IMF(CArchiveOpenCallback_Offset::SetCompleted(const UInt64 *, const UInt64 *bytes)) { if (!Callback) return S_OK; @@ -1140,7 +1198,7 @@ STDMETHODIMP CArchiveOpenCallback_Offset::SetCompleted(const UInt64 *, const UIn return Callback->SetCompleted(&Files, &value); } -STDMETHODIMP CArchiveOpenCallback_Offset::GetProperty(PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CArchiveOpenCallback_Offset::GetProperty(PROPID propID, PROPVARIANT *value)) { if (OpenVolumeCallback) return OpenVolumeCallback->GetProperty(propID, value); @@ -1149,7 +1207,7 @@ STDMETHODIMP CArchiveOpenCallback_Offset::GetProperty(PROPID propID, PROPVARIANT // return E_NOTIMPL; } -STDMETHODIMP CArchiveOpenCallback_Offset::GetStream(const wchar_t *name, IInStream **inStream) +Z7_COM7F_IMF(CArchiveOpenCallback_Offset::GetStream(const wchar_t *name, IInStream **inStream)) { if (OpenVolumeCallback) return OpenVolumeCallback->GetStream(name, inStream); @@ -1193,7 +1251,7 @@ void CArcErrorInfo::ClearErrors() HRESULT CArc::ReadBasicProps(IInArchive *archive, UInt64 startPos, HRESULT openRes) { // OkPhySize_Defined = false; - PhySizeDefined = false; + PhySize_Defined = false; PhySize = 0; Offset = 0; AvailPhySize = FileSize - startPos; @@ -1201,49 +1259,49 @@ HRESULT CArc::ReadBasicProps(IInArchive *archive, UInt64 startPos, HRESULT openR ErrorInfo.ClearErrors(); { NCOM::CPropVariant prop; - RINOK(archive->GetArchiveProperty(kpidErrorFlags, &prop)); + RINOK(archive->GetArchiveProperty(kpidErrorFlags, &prop)) ErrorInfo.ErrorFlags = GetOpenArcErrorFlags(prop, &ErrorInfo.ErrorFlags_Defined); } { NCOM::CPropVariant prop; - RINOK(archive->GetArchiveProperty(kpidWarningFlags, &prop)); + RINOK(archive->GetArchiveProperty(kpidWarningFlags, &prop)) ErrorInfo.WarningFlags = GetOpenArcErrorFlags(prop); } { NCOM::CPropVariant prop; - RINOK(archive->GetArchiveProperty(kpidError, &prop)); + RINOK(archive->GetArchiveProperty(kpidError, &prop)) if (prop.vt != VT_EMPTY) ErrorInfo.ErrorMessage = (prop.vt == VT_BSTR ? prop.bstrVal : L"Unknown error"); } { NCOM::CPropVariant prop; - RINOK(archive->GetArchiveProperty(kpidWarning, &prop)); + RINOK(archive->GetArchiveProperty(kpidWarning, &prop)) if (prop.vt != VT_EMPTY) ErrorInfo.WarningMessage = (prop.vt == VT_BSTR ? prop.bstrVal : L"Unknown warning"); } if (openRes == S_OK || ErrorInfo.IsArc_After_NonOpen()) { - RINOK(Archive_GetArcProp_UInt(archive, kpidPhySize, PhySize, PhySizeDefined)); + RINOK(Archive_GetArcProp_UInt(archive, kpidPhySize, PhySize, PhySize_Defined)) /* RINOK(Archive_GetArcProp_UInt(archive, kpidOkPhySize, OkPhySize, OkPhySize_Defined)); if (!OkPhySize_Defined) { - OkPhySize_Defined = PhySizeDefined; + OkPhySize_Defined = PhySize_Defined; OkPhySize = PhySize; } */ bool offsetDefined; - RINOK(Archive_GetArcProp_Int(archive, kpidOffset, Offset, offsetDefined)); + RINOK(Archive_GetArcProp_Int(archive, kpidOffset, Offset, offsetDefined)) - Int64 globalOffset = startPos + Offset; - AvailPhySize = FileSize - globalOffset; - if (PhySizeDefined) + Int64 globalOffset = (Int64)startPos + Offset; + AvailPhySize = (UInt64)((Int64)FileSize - globalOffset); + if (PhySize_Defined) { - UInt64 endPos = globalOffset + PhySize; + UInt64 endPos = (UInt64)(globalOffset + (Int64)PhySize); if (endPos < FileSize) { AvailPhySize = PhySize; @@ -1259,11 +1317,12 @@ HRESULT CArc::ReadBasicProps(IInArchive *archive, UInt64 startPos, HRESULT openR } /* -static PrintNumber(const char *s, int n) +static void PrintNumber(const char *s, int n) { char temp[100]; sprintf(temp, "%s %d", s, n); - OutputDebugStringA(temp); + // OutputDebugStringA(temp); + printf(temp); } */ @@ -1272,31 +1331,31 @@ HRESULT CArc::PrepareToOpen(const COpenOptions &op, unsigned formatIndex, CMyCom // OutputDebugStringA("a1"); // PrintNumber("formatIndex", formatIndex); - RINOK(op.codecs->CreateInArchive(formatIndex, archive)); + RINOK(op.codecs->CreateInArchive(formatIndex, archive)) // OutputDebugStringA("a2"); if (!archive) return S_OK; - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS if (op.codecs->NeedSetLibCodecs) { const CArcInfoEx &ai = op.codecs->Formats[formatIndex]; if (ai.LibIndex >= 0 ? - !op.codecs->Libs[ai.LibIndex].SetCodecs : + !op.codecs->Libs[(unsigned)ai.LibIndex].SetCodecs : !op.codecs->Libs.IsEmpty()) { CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo; archive.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo); if (setCompressCodecsInfo) { - RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(op.codecs)); + RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(op.codecs)) } } } #endif - #ifndef _SFX + #ifndef Z7_SFX const CArcInfoEx &ai = op.codecs->Formats[formatIndex]; @@ -1326,14 +1385,14 @@ HRESULT CArc::PrepareToOpen(const COpenOptions &op, unsigned formatIndex, CMyCom } } */ - RINOK(SetProperties(archive, *op.props)); + RINOK(SetProperties(archive, *op.props)) } #endif return S_OK; } -#ifndef _SFX +#ifndef Z7_SFX static HRESULT ReadParseItemProps(IInArchive *archive, const CArcInfoEx &ai, NArchive::NParser::CParseItem &pi) { @@ -1341,14 +1400,14 @@ static HRESULT ReadParseItemProps(IInArchive *archive, const CArcInfoEx &ai, NAr pi.FileTime_Defined = false; pi.ArcType = ai.Name; - RINOK(Archive_GetArcBoolProp(archive, kpidIsNotArcType, pi.IsNotArcType)); + RINOK(Archive_GetArcProp_Bool(archive, kpidIsNotArcType, pi.IsNotArcType)) - // RINOK(Archive_GetArcBoolProp(archive, kpidIsSelfExe, pi.IsSelfExe)); + // RINOK(Archive_GetArcProp_Bool(archive, kpidIsSelfExe, pi.IsSelfExe)); pi.IsSelfExe = ai.Flags_PreArc(); { NCOM::CPropVariant prop; - RINOK(archive->GetArchiveProperty(kpidMTime, &prop)); + RINOK(archive->GetArchiveProperty(kpidMTime, &prop)) if (prop.vt == VT_FILETIME) { pi.FileTime_Defined = true; @@ -1359,7 +1418,7 @@ static HRESULT ReadParseItemProps(IInArchive *archive, const CArcInfoEx &ai, NAr if (!pi.FileTime_Defined) { NCOM::CPropVariant prop; - RINOK(archive->GetArchiveProperty(kpidCTime, &prop)); + RINOK(archive->GetArchiveProperty(kpidCTime, &prop)) if (prop.vt == VT_FILETIME) { pi.FileTime_Defined = true; @@ -1369,7 +1428,7 @@ static HRESULT ReadParseItemProps(IInArchive *archive, const CArcInfoEx &ai, NAr { NCOM::CPropVariant prop; - RINOK(archive->GetArchiveProperty(kpidName, &prop)); + RINOK(archive->GetArchiveProperty(kpidName, &prop)) if (prop.vt == VT_BSTR) { pi.Name.SetFromBstr(prop.bstrVal); @@ -1377,7 +1436,7 @@ static HRESULT ReadParseItemProps(IInArchive *archive, const CArcInfoEx &ai, NAr } else { - RINOK(archive->GetArchiveProperty(kpidExtension, &prop)); + RINOK(archive->GetArchiveProperty(kpidExtension, &prop)) if (prop.vt == VT_BSTR) pi.Extension.SetFromBstr(prop.bstrVal); } @@ -1385,14 +1444,14 @@ static HRESULT ReadParseItemProps(IInArchive *archive, const CArcInfoEx &ai, NAr { NCOM::CPropVariant prop; - RINOK(archive->GetArchiveProperty(kpidShortComment, &prop)); + RINOK(archive->GetArchiveProperty(kpidShortComment, &prop)) if (prop.vt == VT_BSTR) pi.Comment.SetFromBstr(prop.bstrVal); } UInt32 numItems; - RINOK(archive->GetNumberOfItems(&numItems)); + RINOK(archive->GetNumberOfItems(&numItems)) // pi.NumSubFiles = numItems; // RINOK(Archive_GetArcProp_UInt(archive, kpidUnpackSize, pi.UnpackSize, pi.UnpackSize_Defined)); @@ -1433,14 +1492,14 @@ HRESULT CArc::CheckZerosTail(const COpenOptions &op, UInt64 offset) { if (!op.stream) return S_OK; - RINOK(op.stream->Seek(offset, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekSet(op.stream, offset)) const UInt32 kBufSize = 1 << 11; Byte buf[kBufSize]; for (;;) { UInt32 processed = 0; - RINOK(op.stream->Read(buf, kBufSize, &processed)); + RINOK(op.stream->Read(buf, kBufSize, &processed)) if (processed == 0) { // ErrorInfo.NonZerosTail = false; @@ -1459,21 +1518,21 @@ HRESULT CArc::CheckZerosTail(const COpenOptions &op, UInt64 offset) } } -#ifndef _SFX -class CExtractCallback_To_OpenCallback: - public IArchiveExtractCallback, - public ICompressProgressInfo, - public CMyUnknownImp -{ + +#ifndef Z7_SFX + +Z7_CLASS_IMP_COM_2( + CExtractCallback_To_OpenCallback + , IArchiveExtractCallback + , ICompressProgressInfo +) + Z7_IFACE_COM7_IMP(IProgress) public: CMyComPtr<IArchiveOpenCallback> Callback; UInt64 Files; UInt64 Offset; - MY_UNKNOWN_IMP2(IArchiveExtractCallback, ICompressProgressInfo) - INTERFACE_IArchiveExtractCallback(;) - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); void Init(IArchiveOpenCallback *callback) { Callback = callback; @@ -1482,17 +1541,17 @@ public: } }; -STDMETHODIMP CExtractCallback_To_OpenCallback::SetTotal(UInt64 /* size */) +Z7_COM7F_IMF(CExtractCallback_To_OpenCallback::SetTotal(UInt64 /* size */)) { return S_OK; } -STDMETHODIMP CExtractCallback_To_OpenCallback::SetCompleted(const UInt64 * /* completeValue */) +Z7_COM7F_IMF(CExtractCallback_To_OpenCallback::SetCompleted(const UInt64 * /* completeValue */)) { return S_OK; } -STDMETHODIMP CExtractCallback_To_OpenCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */) +Z7_COM7F_IMF(CExtractCallback_To_OpenCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */)) { if (Callback) { @@ -1504,22 +1563,23 @@ STDMETHODIMP CExtractCallback_To_OpenCallback::SetRatioInfo(const UInt64 *inSize return S_OK; } -STDMETHODIMP CExtractCallback_To_OpenCallback::GetStream(UInt32 /* index */, ISequentialOutStream **outStream, Int32 /* askExtractMode */) +Z7_COM7F_IMF(CExtractCallback_To_OpenCallback::GetStream(UInt32 /* index */, ISequentialOutStream **outStream, Int32 /* askExtractMode */)) { - *outStream = 0; + *outStream = NULL; return S_OK; } -STDMETHODIMP CExtractCallback_To_OpenCallback::PrepareOperation(Int32 /* askExtractMode */) +Z7_COM7F_IMF(CExtractCallback_To_OpenCallback::PrepareOperation(Int32 /* askExtractMode */)) { return S_OK; } -STDMETHODIMP CExtractCallback_To_OpenCallback::SetOperationResult(Int32 /* operationResult */) +Z7_COM7F_IMF(CExtractCallback_To_OpenCallback::SetOperationResult(Int32 /* operationResult */)) { return S_OK; } + static HRESULT OpenArchiveSpec(IInArchive *archive, bool needPhySize, IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openCallback, @@ -1528,37 +1588,48 @@ static HRESULT OpenArchiveSpec(IInArchive *archive, bool needPhySize, /* if (needPhySize) { - CMyComPtr<IArchiveOpen2> open2; - archive->QueryInterface(IID_IArchiveOpen2, (void **)&open2); + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveOpen2, + open2, archive) if (open2) return open2->ArcOpen2(stream, kOpenFlags_RealPhySize, openCallback); } */ - RINOK(archive->Open(stream, maxCheckStartPosition, openCallback)); + RINOK(archive->Open(stream, maxCheckStartPosition, openCallback)) if (needPhySize) { bool phySize_Defined = false; UInt64 phySize = 0; - RINOK(Archive_GetArcProp_UInt(archive, kpidPhySize, phySize, phySize_Defined)); + RINOK(Archive_GetArcProp_UInt(archive, kpidPhySize, phySize, phySize_Defined)) if (phySize_Defined) return S_OK; - bool phySizeCantBeDetected = false;; - RINOK(Archive_GetArcBoolProp(archive, kpidPhySizeCantBeDetected, phySizeCantBeDetected)); + bool phySizeCantBeDetected = false; + RINOK(Archive_GetArcProp_Bool(archive, kpidPhySizeCantBeDetected, phySizeCantBeDetected)) if (!phySizeCantBeDetected) { - RINOK(archive->Extract(0, (UInt32)(Int32)-1, BoolToInt(true), extractCallback)); + PRF(printf("\n-- !phySize_Defined after Open, call archive->Extract()")); + // It's for bzip2/gz and some xz archives, where Open operation doesn't know phySize. + // But the Handler will know phySize after full archive testing. + RINOK(archive->Extract(NULL, (UInt32)(Int32)-1, BoolToInt(true), extractCallback)) + PRF(printf("\n-- OK")); } } return S_OK; } + + static int FindFormatForArchiveType(CCodecs *codecs, CIntVector orderIndices, const char *name) { FOR_VECTOR (i, orderIndices) - if (StringsAreEqualNoCase_Ascii(codecs->Formats[orderIndices[i]].Name, name)) - return i; + { + int oi = orderIndices[i]; + if (oi >= 0) + if (StringsAreEqualNoCase_Ascii(codecs->Formats[(unsigned)oi].Name, name)) + return (int)i; + } return -1; } @@ -1584,15 +1655,15 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) const UString fileName = ExtractFileNameFromPath(Path); UString extension; { - int dotPos = fileName.ReverseFind_Dot(); + const int dotPos = fileName.ReverseFind_Dot(); if (dotPos >= 0) - extension = fileName.Ptr(dotPos + 1); + extension = fileName.Ptr((unsigned)(dotPos + 1)); } CIntVector orderIndices; bool searchMarkerInHandler = false; - #ifdef _SFX + #ifdef Z7_SFX searchMarkerInHandler = true; #endif @@ -1602,22 +1673,27 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) isMainFormatArr[i] = false; } - UInt64 maxStartOffset = + const UInt64 maxStartOffset = op.openType.MaxStartOffset_Defined ? op.openType.MaxStartOffset : kMaxCheckStartPosition; - #ifndef _SFX + #ifndef Z7_SFX bool isUnknownExt = false; #endif + #ifndef Z7_SFX bool isForced = false; + #endif + unsigned numMainTypes = 0; - int formatIndex = op.openType.FormatIndex; + const int formatIndex = op.openType.FormatIndex; if (formatIndex >= 0) { + #ifndef Z7_SFX isForced = true; + #endif orderIndices.Add(formatIndex); numMainTypes = 1; isMainFormatArr[(unsigned)formatIndex] = true; @@ -1627,12 +1703,12 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) else { unsigned numFinded = 0; - #ifndef _SFX + #ifndef Z7_SFX bool isPrearcExt = false; #endif { - #ifndef _SFX + #ifndef Z7_SFX bool isZip = false; bool isRar = false; @@ -1654,10 +1730,12 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) isNumber = true; } if (isNumber) + { if (c == 'z' || c == 'Z') isZip = true; else isRar = true; + } } #endif @@ -1667,29 +1745,29 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) const CArcInfoEx &ai = op.codecs->Formats[i]; if (IgnoreSplit || !op.openType.CanReturnArc) - if (ai.IsSplit()) + if (ai.Is_Split()) continue; - if (op.excludedFormats->FindInSorted(i) >= 0) + if (op.excludedFormats->FindInSorted((int)i) >= 0) continue; - #ifndef _SFX + #ifndef Z7_SFX if (IsPreArcFormat(ai)) isPrearcExt = true; #endif if (ai.FindExtension(extension) >= 0 - #ifndef _SFX - || isZip && StringsAreEqualNoCase_Ascii(ai.Name, "zip") - || isRar && StringsAreEqualNoCase_Ascii(ai.Name, "rar") + #ifndef Z7_SFX + || (isZip && ai.Is_Zip()) + || (isRar && ai.Is_Rar()) #endif ) { // PrintNumber("orderIndices.Insert", i); - orderIndices.Insert(numFinded++, i); + orderIndices.Insert(numFinded++, (int)i); isMainFormatArr[i] = true; } else - orderIndices.Add(i); + orderIndices.Add((int)i); } } @@ -1709,11 +1787,11 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) } */ - #ifndef _SFX + #ifndef Z7_SFX if (op.stream && orderIndices.Size() >= 2) { - RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekToBegin(op.stream)) CByteBuffer byteBuffer; CIntVector orderIndices2; if (numFinded == 0 || IsExeExt(extension)) @@ -1722,21 +1800,21 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) } else if (extension.IsEqualTo("000") || extension.IsEqualTo("001")) { - int i = FindFormatForArchiveType(op.codecs, orderIndices, "rar"); + const int i = FindFormatForArchiveType(op.codecs, orderIndices, "rar"); if (i >= 0) { const size_t kBufSize = (1 << 10); byteBuffer.Alloc(kBufSize); size_t processedSize = kBufSize; - RINOK(ReadStream(op.stream, byteBuffer, &processedSize)); + RINOK(ReadStream(op.stream, byteBuffer, &processedSize)) if (processedSize >= 16) { const Byte *buf = byteBuffer; const Byte kRarHeader[] = { 0x52 , 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00 }; if (TestSignature(buf, kRarHeader, 7) && buf[9] == 0x73 && (buf[10] & 1) != 0) { - orderIndices2.Add(orderIndices[i]); - orderIndices[i] = -1; + orderIndices2.Add(orderIndices[(unsigned)i]); + orderIndices[(unsigned)i] = -1; if (i >= (int)numFinded) numFinded++; } @@ -1748,17 +1826,33 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) const size_t kBufSize = (1 << 10); byteBuffer.Alloc(kBufSize); size_t processedSize = kBufSize; - RINOK(ReadStream(op.stream, byteBuffer, &processedSize)); + RINOK(ReadStream(op.stream, byteBuffer, &processedSize)) if (processedSize == 0) return S_FALSE; /* check type order: - 1) matched extension, no signuature - 2) matched extension, matched signuature + 0) matched_extension && Backward + 1) matched_extension && (no_signuature || SignatureOffset != 0) + 2) matched_extension && (matched_signature) // 3) no signuature // 4) matched signuature */ + // we move index from orderIndices to orderIndices2 for priority handlers. + + for (unsigned i = 0; i < numFinded; i++) + { + const int index = orderIndices[i]; + if (index < 0) + continue; + const CArcInfoEx &ai = op.codecs->Formats[(unsigned)index]; + if (ai.Flags_BackwardOpen()) + { + // backward doesn't need start signatures + orderIndices2.Add(index); + orderIndices[i] = -1; + } + } MakeCheckOrder(op.codecs, orderIndices, numFinded, orderIndices2, NULL, 0); MakeCheckOrder(op.codecs, orderIndices, numFinded, orderIndices2, byteBuffer, processedSize); @@ -1768,7 +1862,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) FOR_VECTOR (i, orderIndices) { - int val = orderIndices[i]; + const int val = orderIndices[i]; if (val != -1) orderIndices2.Add(val); } @@ -1777,21 +1871,21 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) if (orderIndices.Size() >= 2) { - int iIso = FindFormatForArchiveType(op.codecs, orderIndices, "iso"); - int iUdf = FindFormatForArchiveType(op.codecs, orderIndices, "udf"); + const int iIso = FindFormatForArchiveType(op.codecs, orderIndices, "iso"); + const int iUdf = FindFormatForArchiveType(op.codecs, orderIndices, "udf"); if (iUdf > iIso && iIso >= 0) { - int isoIndex = orderIndices[iIso]; - int udfIndex = orderIndices[iUdf]; - orderIndices[iUdf] = isoIndex; - orderIndices[iIso] = udfIndex; + const int isoIndex = orderIndices[(unsigned)iIso]; + const int udfIndex = orderIndices[(unsigned)iUdf]; + orderIndices[(unsigned)iUdf] = isoIndex; + orderIndices[(unsigned)iIso] = udfIndex; } } numMainTypes = numFinded; isUnknownExt = (numMainTypes == 0) || isPrearcExt; - #else // _SFX + #else // Z7_SFX numMainTypes = orderIndices.Size(); @@ -1805,13 +1899,12 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) UInt64 fileSize = 0; if (op.stream) { - RINOK(op.stream->Seek(0, STREAM_SEEK_END, &fileSize)); - RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL)); + RINOK(InStream_GetSize_SeekToBegin(op.stream, fileSize)) } FileSize = fileSize; - #ifndef _SFX + #ifndef Z7_SFX CBoolArr skipFrontalFormat(op.codecs->Formats.Size()); { @@ -1838,15 +1931,18 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) for (unsigned i = 0; i < numCheckTypes; i++) { FormatIndex = orderIndices[i]; + + // orderIndices[] item cannot be negative here bool exactOnly = false; - #ifndef _SFX + #ifndef Z7_SFX - const CArcInfoEx &ai = op.codecs->Formats[FormatIndex]; + const CArcInfoEx &ai = op.codecs->Formats[(unsigned)FormatIndex]; // OutputDebugStringW(ai.Name); if (i >= numMainTypes) { + // here we allow mismatched extension only for backward handlers if (!ai.Flags_BackwardOpen() // && !ai.Flags_PureStartOpen() ) @@ -1858,16 +1954,16 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) // Some handlers do not set total bytes. So we set it here if (op.callback) - RINOK(op.callback->SetTotal(NULL, &fileSize)); + RINOK(op.callback->SetTotal(NULL, &fileSize)) if (op.stream) { - RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekToBegin(op.stream)) } CMyComPtr<IInArchive> archive; - RINOK(PrepareToOpen(op, FormatIndex, archive)); + RINOK(PrepareToOpen(op, (unsigned)FormatIndex, archive)) if (!archive) continue; @@ -1886,13 +1982,13 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) result = openSeq->OpenSeq(op.seqStream); } - RINOK(ReadBasicProps(archive, 0, result)); + RINOK(ReadBasicProps(archive, 0, result)) if (result == S_FALSE) { bool isArc = ErrorInfo.IsArc_After_NonOpen(); - #ifndef _SFX + #ifndef Z7_SFX // if it's archive, we allow another open attempt for parser if (!mode.CanReturnParser || !isArc) skipFrontalFormat[(unsigned)FormatIndex] = true; @@ -1912,7 +2008,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) // if (formatIndex < 0 && !searchMarkerInHandler) { // if bad archive was detected, we don't need additional open attempts - #ifndef _SFX + #ifndef Z7_SFX if (!IsPreArcFormat(ai) /* || !mode.SkipSfxStub */) #endif return S_FALSE; @@ -1921,7 +2017,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) } /* - #ifndef _SFX + #ifndef Z7_SFX if (IsExeExt(extension) || ai.Flags_PreArc()) { // openOnlyFullArc = false; @@ -1934,9 +2030,9 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) continue; } - RINOK(result); + RINOK(result) - #ifndef _SFX + #ifndef Z7_SFX bool isMainFormat = isMainFormatArr[(unsigned)FormatIndex]; const COpenSpecFlags &specFlags = mode.GetSpec(isForced, isMainFormat, isUnknownExt); @@ -1944,7 +2040,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) bool thereIsTail = ErrorInfo.ThereIsTail; if (thereIsTail && mode.ZerosTailIsAllowed) { - RINOK(CheckZerosTail(op, Offset + PhySize)); + RINOK(CheckZerosTail(op, (UInt64)(Offset + (Int64)PhySize))) if (ErrorInfo.IgnoreTail) thereIsTail = false; } @@ -1998,7 +2094,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) - #ifndef _SFX + #ifndef Z7_SFX if (!op.stream) return S_FALSE; @@ -2012,7 +2108,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) } else { - const CArcInfoEx &ai = op.codecs->Formats[formatIndex]; + const CArcInfoEx &ai = op.codecs->Formats[(unsigned)formatIndex]; if (ai.FindExtension(extension) >= 0) { if (ai.Flags_FindSignature() && searchMarkerInHandler) @@ -2043,9 +2139,9 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) endOfFile = true; } byteBuffer.Alloc(bufSize); - RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekToBegin(op.stream)) processedSize = bufSize; - RINOK(ReadStream(op.stream, byteBuffer, &processedSize)); + RINOK(ReadStream(op.stream, byteBuffer, &processedSize)) if (processedSize == 0) return S_FALSE; if (processedSize < bufSize) @@ -2059,16 +2155,22 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) for (i = 0; i < orderIndices.Size(); i++) { - unsigned form = orderIndices[i]; + // orderIndices[] item cannot be negative here + unsigned form = (unsigned)orderIndices[i]; if (skipFrontalFormat[form]) continue; + const CArcInfoEx &ai = op.codecs->Formats[form]; - if (ai.IsSplit()) + + if (ai.Is_Split()) { - splitIndex = form; + splitIndex = (int)form; continue; } + if (ai.Flags_ByExtOnlyOpen()) + continue; + if (ai.IsArcFunc) { UInt32 isArcRes = ai.IsArcFunc(byteBuffer, processedSize); @@ -2081,7 +2183,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) continue; } - bool isNewStyleSignature = IsNewStyleSignature(ai); + const bool isNewStyleSignature = IsNewStyleSignature(ai); bool needCheck = !isNewStyleSignature || ai.Signatures.IsEmpty() || ai.Flags_PureStartOpen() @@ -2094,13 +2196,12 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) for (k = 0; k < ai.Signatures.Size(); k++) { const CByteBuffer &sig = ai.Signatures[k]; - UInt32 signatureEnd = ai.SignatureOffset + (UInt32)sig.Size(); - if (processedSize < signatureEnd) + if (processedSize < ai.SignatureOffset + sig.Size()) { if (!endOfFile) needCheck = true; } - else if (memcmp(sig, byteBuffer + ai.SignatureOffset, sig.Size()) == 0) + else if (TestSignature(sig, byteBuffer + ai.SignatureOffset, sig.Size())) break; } if (k != ai.Signatures.Size()) @@ -2114,20 +2215,20 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) } if (splitIndex >= 0) - sortedFormats.Insert(0, splitIndex); + sortedFormats.Insert(0, (unsigned)splitIndex); for (i = 0; i < sortedFormats.Size(); i++) { - FormatIndex = sortedFormats[i]; - const CArcInfoEx &ai = op.codecs->Formats[FormatIndex]; + FormatIndex = (int)sortedFormats[i]; + const CArcInfoEx &ai = op.codecs->Formats[(unsigned)FormatIndex]; if (op.callback) - RINOK(op.callback->SetTotal(NULL, &fileSize)); + RINOK(op.callback->SetTotal(NULL, &fileSize)) - RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekToBegin(op.stream)) CMyComPtr<IInArchive> archive; - RINOK(PrepareToOpen(op, FormatIndex, archive)); + RINOK(PrepareToOpen(op, (unsigned)FormatIndex, archive)) if (!archive) continue; @@ -2140,7 +2241,10 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) result = archive->Open(op.stream, &searchLimit, op.callback); else */ - result = OpenArchiveSpec(archive, !mode.CanReturnArc, op.stream, &searchLimit, op.callback, extractCallback_To_OpenCallback); + // if (!CanReturnArc), it's ParserMode, and we need phy size + result = OpenArchiveSpec(archive, + !mode.CanReturnArc, // needPhySize + op.stream, &searchLimit, op.callback, extractCallback_To_OpenCallback); } if (result == S_FALSE) @@ -2150,9 +2254,9 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) // printf(" OpenForSize Error"); continue; } - RINOK(result); + RINOK(result) - RINOK(ReadBasicProps(archive, 0, result)); + RINOK(ReadBasicProps(archive, 0, result)) if (Offset > 0) { @@ -2162,12 +2266,12 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) } NArchive::NParser::CParseItem pi; - pi.Offset = Offset; + pi.Offset = (UInt64)Offset; pi.Size = AvailPhySize; // bool needScan = false; - if (!PhySizeDefined) + if (!PhySize_Defined) { // it's for Z format pi.LenIsUnknown = true; @@ -2189,7 +2293,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) if (mode.CanReturnArc) { - bool isMainFormat = isMainFormatArr[(unsigned)FormatIndex]; + const bool isMainFormat = isMainFormatArr[(unsigned)FormatIndex]; const COpenSpecFlags &specFlags = mode.GetSpec(isForced, isMainFormat, isUnknownExt); bool openCur = false; @@ -2199,7 +2303,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) { if (mode.ZerosTailIsAllowed) { - RINOK(CheckZerosTail(op, Offset + PhySize)); + RINOK(CheckZerosTail(op, (UInt64)(Offset + (Int64)PhySize))) if (ErrorInfo.IgnoreTail) openCur = true; } @@ -2239,7 +2343,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) continue; // printf("\nAdd offset = %d", (int)pi.Offset); - RINOK(ReadParseItemProps(archive, ai, pi)); + RINOK(ReadParseItemProps(archive, ai, pi)) handlerSpec->AddItem(pi); } } @@ -2294,7 +2398,9 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) int index = orderIndices[i]; if (index < 0) continue; - const CArcInfoEx &ai = op.codecs->Formats[index]; + const CArcInfoEx &ai = op.codecs->Formats[(unsigned)index]; + if (ai.Flags_ByExtOnlyOpen()) + continue; bool isDifficult = false; // if (ai.Version < 0x91F) // we don't use parser with old DLL (before 9.31) if (!ai.NewInterface) @@ -2317,7 +2423,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) continue; } thereAreHandlersForSearch = true; - UInt32 v = HASH_VAL(sig, 0); + UInt32 v = HASH_VAL(sig); unsigned sigIndex = arc2sig[(unsigned)index] + k; prevs[sigIndex] = hash[v]; hash[v] = (Byte)sigIndex; @@ -2325,8 +2431,8 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) } if (isDifficult) { - difficultFormats.Add(index); - difficultBools[index] = true; + difficultFormats.Add((unsigned)index); + difficultBools[(unsigned)index] = true; } } @@ -2336,7 +2442,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) // canReturnTailArc = true; } - RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekToBegin(op.stream)) CLimitedCachedInStream *limitedStreamSpec = new CLimitedCachedInStream; CMyComPtr<IInStream> limitedStream = limitedStreamSpec; @@ -2350,13 +2456,13 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) openCallback_Offset = openCallback_Offset_Spec; openCallback_Offset_Spec->Callback = op.callback; openCallback_Offset_Spec->Callback.QueryInterface(IID_IArchiveOpenVolumeCallback, &openCallback_Offset_Spec->OpenVolumeCallback); - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO openCallback_Offset_Spec->Callback.QueryInterface(IID_ICryptoGetTextPassword, &openCallback_Offset_Spec->GetTextPassword); #endif } if (op.callback) - RINOK(op.callback->SetTotal(NULL, &fileSize)); + RINOK(op.callback->SetTotal(NULL, &fileSize)) CByteBuffer &byteBuffer = limitedStreamSpec->Buffer; byteBuffer.Alloc(kBufSize); @@ -2394,8 +2500,8 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) size_t processedSize = kBufSize - bytesInBuf; // printf("\nRead ask = %d", (unsigned)processedSize); UInt64 seekPos = bufPhyPos + bytesInBuf; - RINOK(op.stream->Seek(bufPhyPos + bytesInBuf, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream(op.stream, byteBuffer + bytesInBuf, &processedSize)); + RINOK(InStream_SeekSet(op.stream, bufPhyPos + bytesInBuf)) + RINOK(ReadStream(op.stream, byteBuffer + bytesInBuf, &processedSize)) // printf(" processed = %d", (unsigned)processedSize); if (processedSize == 0) { @@ -2440,6 +2546,9 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) } } + if (bytesInBuf <= (size_t)posInBuf) + break; + bool useOffsetCallback = false; if (openCallback_Offset) { @@ -2450,7 +2559,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) if (pos >= callbackPrev + (1 << 23)) { - RINOK(openCallback_Offset_Spec->SetCompleted(NULL, NULL)); + RINOK(openCallback_Offset->SetCompleted(NULL, NULL)) callbackPrev = pos; } } @@ -2464,7 +2573,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) } } - size_t availSize = bytesInBuf - (size_t)posInBuf; + const size_t availSize = bytesInBuf - (size_t)posInBuf; if (availSize < kNumHashBytes) break; size_t scanSize = availSize - @@ -2489,17 +2598,19 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) scanSize++; const Byte *buf = byteBuffer + (size_t)posInBuf; + const Byte *bufLimit = buf + scanSize; size_t ppp = 0; if (!needCheckStartOpen) { - for (; ppp < scanSize && hash[HASH_VAL(buf, ppp)] == 0xFF; ppp++); + for (; buf < bufLimit && hash[HASH_VAL(buf)] == 0xFF; buf++); + ppp = (size_t)(buf - (byteBuffer + (size_t)posInBuf)); pos += ppp; - if (ppp == scanSize) + if (buf == bufLimit) continue; } - UInt32 v = HASH_VAL(buf, ppp); + UInt32 v = HASH_VAL(buf); bool nextNeedCheckStartOpen = true; unsigned i = hash[v]; unsigned indexOfDifficult = 0; @@ -2539,7 +2650,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) const CByteBuffer &sig = ai.Signatures[sigIndex]; if (ppp + sig.Size() > availSize - || !TestSignature(buf + ppp, sig, sig.Size())) + || !TestSignature(buf, sig, sig.Size())) continue; // printf("\nSignature OK: %10S %8x %5d", (const wchar_t *)ai.Name, (int)pos, (int)(pos - prevPos)); // prevPos = pos; @@ -2571,10 +2682,10 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) if (ai.IsArcFunc && startArcPos >= bufPhyPos) { - size_t offsetInBuf = (size_t)(startArcPos - bufPhyPos); + const size_t offsetInBuf = (size_t)(startArcPos - bufPhyPos); if (offsetInBuf < bytesInBuf) { - UInt32 isArcRes = ai.IsArcFunc(byteBuffer + offsetInBuf, bytesInBuf - offsetInBuf); + const UInt32 isArcRes = ai.IsArcFunc(byteBuffer + offsetInBuf, bytesInBuf - offsetInBuf); if (isArcRes == k_IsArc_Res_NO) continue; if (isArcRes == k_IsArc_Res_NEED_MORE && endOfFile) @@ -2590,34 +2701,30 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) // printf("\nIsArc OK: %S", (const wchar_t *)ai.Name); } - /* - if (pos == 67109888) - pos = pos; - */ PRF(printf("\npos = %9I64d : %S", pos, (const wchar_t *)ai.Name)); - bool isMainFormat = isMainFormatArr[index]; + const bool isMainFormat = isMainFormatArr[index]; const COpenSpecFlags &specFlags = mode.GetSpec(isForced, isMainFormat, isUnknownExt); CMyComPtr<IInArchive> archive; - RINOK(PrepareToOpen(op, index, archive)); + RINOK(PrepareToOpen(op, index, archive)) if (!archive) return E_FAIL; // OutputDebugStringW(ai.Name); - UInt64 rem = fileSize - startArcPos; + const UInt64 rem = fileSize - startArcPos; UInt64 arcStreamOffset = 0; if (ai.Flags_UseGlobalOffset()) { - limitedStreamSpec->InitAndSeek(0, fileSize); - limitedStream->Seek(startArcPos, STREAM_SEEK_SET, NULL); + RINOK(limitedStreamSpec->InitAndSeek(0, fileSize)) + RINOK(InStream_SeekSet(limitedStream, startArcPos)) } else { - limitedStreamSpec->InitAndSeek(startArcPos, rem); + RINOK(limitedStreamSpec->InitAndSeek(startArcPos, rem)) arcStreamOffset = startArcPos; } @@ -2633,33 +2740,42 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) extractCallback_To_OpenCallback_Spec->Files = 0; extractCallback_To_OpenCallback_Spec->Offset = startArcPos; - HRESULT result = OpenArchiveSpec(archive, true, limitedStream, &maxCheckStartPosition, + HRESULT result = OpenArchiveSpec(archive, + true, // needPhySize + limitedStream, &maxCheckStartPosition, useOffsetCallback ? (IArchiveOpenCallback *)openCallback_Offset : (IArchiveOpenCallback *)op.callback, extractCallback_To_OpenCallback); - RINOK(ReadBasicProps(archive, ai.Flags_UseGlobalOffset() ? 0 : startArcPos, result)); + RINOK(ReadBasicProps(archive, ai.Flags_UseGlobalOffset() ? 0 : startArcPos, result)) bool isOpen = false; + if (result == S_FALSE) { if (!mode.CanReturnParser) { if (formatIndex < 0 && ErrorInfo.IsArc_After_NonOpen()) { - ErrorInfo.ErrorFormatIndex = index; + ErrorInfo.ErrorFormatIndex = (int)index; NonOpen_ErrorInfo = ErrorInfo; // if archive was detected, we don't need additional open attempts return S_FALSE; } continue; } - if (!ErrorInfo.IsArc_After_NonOpen() || !PhySizeDefined || PhySize == 0) + if (!ErrorInfo.IsArc_After_NonOpen() || !PhySize_Defined || PhySize == 0) continue; } else { + if (PhySize_Defined && PhySize == 0) + { + PRF(printf(" phySize_Defined && PhySize == 0 ")); + // we skip that epmty archive case with unusual unexpected (PhySize == 0) from Code function. + continue; + } isOpen = true; - RINOK(result); + RINOK(result) PRF(printf(" OK ")); } @@ -2671,13 +2787,14 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) pi.Offset = startArcPos; if (ai.Flags_UseGlobalOffset()) - pi.Offset = Offset; + pi.Offset = (UInt64)Offset; else if (Offset != 0) return E_FAIL; - UInt64 arcRem = FileSize - pi.Offset; + + const UInt64 arcRem = FileSize - pi.Offset; UInt64 phySize = arcRem; - bool phySizeDefined = PhySizeDefined; - if (phySizeDefined) + const bool phySize_Defined = PhySize_Defined; + if (phySize_Defined) { if (pi.Offset + PhySize > FileSize) { @@ -2703,9 +2820,9 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) bool needScan = false; - if (isOpen && !phySizeDefined) + if (isOpen && !phySize_Defined) { - // it's for Z format + // it's for Z format, or bzip2,gz,xz with phySize that was not detected pi.LenIsUnknown = true; needScan = true; phySize = arcRem; @@ -2722,7 +2839,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) /* if (needSkipFullArc) - if (pi.Offset == 0 && phySizeDefined && pi.Size >= fileSize) + if (pi.Offset == 0 && phySize_Defined && pi.Size >= fileSize) continue; */ if (pi.Offset == 0 && !pi.LenIsUnknown && pi.Size >= FileSize) @@ -2748,9 +2865,9 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) pos = pi.Offset + pi.Size; - RINOK(ReadParseItemProps(archive, ai, pi)); + RINOK(ReadParseItemProps(archive, ai, pi)) - if (pi.Offset < startArcPos && !mode.EachPos /* && phySizeDefined */) + if (pi.Offset < startArcPos && !mode.EachPos /* && phySize_Defined */) { /* It's for DMG format. This code deletes all previous items that are included to current item */ @@ -2769,7 +2886,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) } - if (isOpen && mode.CanReturnArc && phySizeDefined) + if (isOpen && mode.CanReturnArc && phySize_Defined) { // if (pi.Offset + pi.Size >= fileSize) bool openCur = false; @@ -2777,7 +2894,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) bool thereIsTail = ErrorInfo.ThereIsTail; if (thereIsTail && mode.ZerosTailIsAllowed) { - RINOK(CheckZerosTail(op, arcStreamOffset + Offset + PhySize)); + RINOK(CheckZerosTail(op, (UInt64)((Int64)arcStreamOffset + Offset + (Int64)PhySize))) if (ErrorInfo.IgnoreTail) thereIsTail = false; } @@ -2785,10 +2902,12 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) if (pi.Offset != 0) { if (!pi.IsNotArcType) + { if (thereIsTail) openCur = specFlags.CanReturnMid; else openCur = specFlags.CanReturnTail; + } } else { @@ -2796,11 +2915,11 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) openCur = true; else openCur = specFlags.CanReturnFrontal; - if (formatIndex >= -2) openCur = true; } + if (formatIndex < 0 && pi.IsSelfExe /* && mode.SkipSfxStub */) openCur = false; @@ -2827,7 +2946,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) { InStream = op.stream; Archive = archive; - FormatIndex = index; + FormatIndex = (int)index; ArcStreamOffset = arcStreamOffset; return S_OK; } @@ -2841,7 +2960,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) } */ - pi.FormatIndex = index; + pi.FormatIndex = (int)index; // printf("\nAdd offset = %d", (int)pi.Offset); handlerSpec->AddItem(pi); @@ -2896,9 +3015,12 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) return S_OK; } + + + HRESULT CArc::OpenStream(const COpenOptions &op) { - RINOK(OpenStream2(op)); + RINOK(OpenStream2(op)) // PrintNumber("op.formatIndex 3", op.formatIndex); if (Archive) @@ -2908,25 +3030,25 @@ HRESULT CArc::OpenStream(const COpenOptions &op) Archive->QueryInterface(IID_IArchiveGetRawProps, (void **)&GetRawProps); Archive->QueryInterface(IID_IArchiveGetRootProps, (void **)&GetRootProps); - RINOK(Archive_GetArcBoolProp(Archive, kpidIsTree, IsTree)); - RINOK(Archive_GetArcBoolProp(Archive, kpidIsDeleted, Ask_Deleted)); - RINOK(Archive_GetArcBoolProp(Archive, kpidIsAltStream, Ask_AltStream)); - RINOK(Archive_GetArcBoolProp(Archive, kpidIsAux, Ask_Aux)); - RINOK(Archive_GetArcBoolProp(Archive, kpidINode, Ask_INode)); - RINOK(Archive_GetArcBoolProp(Archive, kpidReadOnly, IsReadOnly)); + RINOK(Archive_GetArcProp_Bool(Archive, kpidIsTree, IsTree)) + RINOK(Archive_GetArcProp_Bool(Archive, kpidIsDeleted, Ask_Deleted)) + RINOK(Archive_GetArcProp_Bool(Archive, kpidIsAltStream, Ask_AltStream)) + RINOK(Archive_GetArcProp_Bool(Archive, kpidIsAux, Ask_Aux)) + RINOK(Archive_GetArcProp_Bool(Archive, kpidINode, Ask_INode)) + RINOK(Archive_GetArcProp_Bool(Archive, kpidReadOnly, IsReadOnly)) const UString fileName = ExtractFileNameFromPath(Path); UString extension; { int dotPos = fileName.ReverseFind_Dot(); if (dotPos >= 0) - extension = fileName.Ptr(dotPos + 1); + extension = fileName.Ptr((unsigned)(dotPos + 1)); } DefaultName.Empty(); if (FormatIndex >= 0) { - const CArcInfoEx &ai = op.codecs->Formats[FormatIndex]; + const CArcInfoEx &ai = op.codecs->Formats[(unsigned)FormatIndex]; if (ai.Exts.Size() == 0) DefaultName = GetDefaultName2(fileName, UString(), UString()); else @@ -2934,7 +3056,7 @@ HRESULT CArc::OpenStream(const COpenOptions &op) int subExtIndex = ai.FindExtension(extension); if (subExtIndex < 0) subExtIndex = 0; - const CArcExtInfo &extInfo = ai.Exts[subExtIndex]; + const CArcExtInfo &extInfo = ai.Exts[(unsigned)subExtIndex]; DefaultName = GetDefaultName2(fileName, extInfo.Ext, extInfo.AddExt); } } @@ -2943,13 +3065,13 @@ HRESULT CArc::OpenStream(const COpenOptions &op) return S_OK; } -#ifdef _SFX +#ifdef Z7_SFX #ifdef _WIN32 - static const char *k_ExeExt = ".exe"; + #define k_ExeExt ".exe" static const unsigned k_ExeExt_Len = 4; #else - static const char *k_ExeExt = ""; + #define k_ExeExt "" static const unsigned k_ExeExt_Len = 0; #endif @@ -2972,11 +3094,9 @@ HRESULT CArc::OpenStreamOrFile(COpenOptions &op) fileStream = fileStreamSpec; Path = filePath; if (!fileStreamSpec->Open(us2fs(Path))) - { - return GetLastError(); - } + return GetLastError_noZero_HRESULT(); op.stream = fileStream; - #ifdef _SFX + #ifdef Z7_SFX IgnoreSplit = true; #endif } @@ -2985,7 +3105,7 @@ HRESULT CArc::OpenStreamOrFile(COpenOptions &op) if (callback) { UInt64 fileSize; - RINOK(op.stream->Seek(0, STREAM_SEEK_END, &fileSize)); + RINOK(InStream_GetSize_SeekToEnd(op.stream, fileSize)); RINOK(op.callback->SetTotal(NULL, &fileSize)) } */ @@ -2993,7 +3113,7 @@ HRESULT CArc::OpenStreamOrFile(COpenOptions &op) HRESULT res = OpenStream(op); IgnoreSplit = false; - #ifdef _SFX + #ifdef Z7_SFX if (res != S_FALSE || !fileStreamSpec @@ -3009,13 +3129,13 @@ HRESULT CArc::OpenStreamOrFile(COpenOptions &op) FOR_VECTOR (i, op.codecs->Formats) { const CArcInfoEx &ai = op.codecs->Formats[i]; - if (ai.IsSplit()) + if (ai.Is_Split()) continue; UString path3 = path2; - path3 += L'.'; + path3.Add_Dot(); path3 += ai.GetMainExt(); // "7z" for SFX. Path = path3; - Path.AddAscii(".001"); + Path += ".001"; bool isOk = op.callbackSpec->SetSecondFileInfo(us2fs(Path)); if (!isOk) { @@ -3058,7 +3178,7 @@ HRESULT CArchiveLink::Close() for (unsigned i = Arcs.Size(); i != 0;) { i--; - RINOK(Arcs[i].Close()); + RINOK(Arcs[i].Close()) } IsOpen = false; // ErrorsText.Empty(); @@ -3191,13 +3311,13 @@ HRESULT CArchiveLink::Open(COpenOptions &op) UInt32 mainSubfile; { NCOM::CPropVariant prop; - RINOK(arc.Archive->GetArchiveProperty(kpidMainSubfile, &prop)); + RINOK(arc.Archive->GetArchiveProperty(kpidMainSubfile, &prop)) if (prop.vt == VT_UI4) mainSubfile = prop.ulVal; else break; UInt32 numItems; - RINOK(arc.Archive->GetNumberOfItems(&numItems)); + RINOK(arc.Archive->GetNumberOfItems(&numItems)) if (mainSubfile >= numItems) break; } @@ -3216,16 +3336,17 @@ HRESULT CArchiveLink::Open(COpenOptions &op) break; CArc arc2; - RINOK(arc.GetItemPath(mainSubfile, arc2.Path)); + RINOK(arc.GetItem_Path(mainSubfile, arc2.Path)) bool zerosTailIsAllowed; - RINOK(Archive_GetItemBoolProp(arc.Archive, mainSubfile, kpidZerosTailIsAllowed, zerosTailIsAllowed)); + RINOK(Archive_GetItemBoolProp(arc.Archive, mainSubfile, kpidZerosTailIsAllowed, zerosTailIsAllowed)) if (op.callback) { - CMyComPtr<IArchiveOpenSetSubArchiveName> setSubArchiveName; - op.callback->QueryInterface(IID_IArchiveOpenSetSubArchiveName, (void **)&setSubArchiveName); + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveOpenSetSubArchiveName, + setSubArchiveName, op.callback) if (setSubArchiveName) setSubArchiveName->SetSubArchiveName(arc2.Path); } @@ -3236,7 +3357,7 @@ HRESULT CArchiveLink::Open(COpenOptions &op) CIntVector excl; COpenOptions op2; - #ifndef _SFX + #ifndef Z7_SFX op2.props = op.props; #endif op2.codecs = op.codecs; @@ -3259,8 +3380,8 @@ HRESULT CArchiveLink::Open(COpenOptions &op) NonOpen_ArcPath = arc2.Path; break; } - RINOK(result); - RINOK(arc.GetItemMTime(mainSubfile, arc2.MTime, arc2.MTimeDefined)); + RINOK(result) + RINOK(arc.GetItem_MTime(mainSubfile, arc2.MTime)) Arcs.Add(arc2); } IsOpen = !Arcs.IsEmpty(); @@ -3279,7 +3400,7 @@ HRESULT CArchiveLink::Open2(COpenOptions &op, IOpenCallbackUI *callbackUI) if (!op.stream && !op.stdInMode) { NFile::NDir::GetFullPathAndSplit(us2fs(op.filePath), prefix, name); - openCallbackSpec->Init(prefix, name); + RINOK(openCallbackSpec->Init2(prefix, name)) } else { @@ -3294,7 +3415,7 @@ HRESULT CArchiveLink::Open2(COpenOptions &op, IOpenCallbackUI *callbackUI) PasswordWasAsked = openCallbackSpec->PasswordWasAsked; // Password = openCallbackSpec->Password; - RINOK(res); + RINOK(res) // VolumePaths.Add(fs2us(prefix + name)); FOR_VECTOR (i, openCallbackSpec->FileNames_WasUsed) @@ -3309,7 +3430,7 @@ HRESULT CArchiveLink::Open2(COpenOptions &op, IOpenCallbackUI *callbackUI) return S_OK; } -HRESULT CArc::ReOpen(const COpenOptions &op) +HRESULT CArc::ReOpen(const COpenOptions &op, IArchiveOpenCallback *openCallback_Additional) { ErrorInfo.ClearErrors(); ErrorInfo.ErrorFormatIndex = -1; @@ -3317,8 +3438,9 @@ HRESULT CArc::ReOpen(const COpenOptions &op) UInt64 fileSize = 0; if (op.stream) { - RINOK(op.stream->Seek(0, STREAM_SEEK_END, &fileSize)); - RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL)); + RINOK(InStream_SeekToBegin(op.stream)) + RINOK(InStream_AtBegin_GetSize(op.stream, fileSize)) + // RINOK(InStream_GetSize_SeekToBegin(op.stream, fileSize)) } FileSize = fileSize; @@ -3331,20 +3453,23 @@ HRESULT CArc::ReOpen(const COpenOptions &op) CTailInStream *tailStreamSpec = new CTailInStream; stream2 = tailStreamSpec; tailStreamSpec->Stream = op.stream; - tailStreamSpec->Offset = globalOffset; + tailStreamSpec->Offset = (UInt64)globalOffset; tailStreamSpec->Init(); - RINOK(tailStreamSpec->SeekToStart()); + RINOK(tailStreamSpec->SeekToStart()) } // There are archives with embedded STUBs (like ZIP), so we must support signature scanning // But for another archives we can use 0 here. So the code can be fixed !!! UInt64 maxStartPosition = kMaxCheckStartPosition; - HRESULT res = Archive->Open(stream2, &maxStartPosition, op.callback); + IArchiveOpenCallback *openCallback = openCallback_Additional; + if (!openCallback) + openCallback = op.callback; + HRESULT res = Archive->Open(stream2, &maxStartPosition, openCallback); if (res == S_OK) { - RINOK(ReadBasicProps(Archive, globalOffset, res)); - ArcStreamOffset = globalOffset; + RINOK(ReadBasicProps(Archive, (UInt64)globalOffset, res)) + ArcStreamOffset = (UInt64)globalOffset; if (ArcStreamOffset != 0) InStream = op.stream; } @@ -3356,7 +3481,7 @@ HRESULT CArchiveLink::Open3(COpenOptions &op, IOpenCallbackUI *callbackUI) HRESULT res = Open2(op, callbackUI); if (callbackUI) { - RINOK(callbackUI->Open_Finished()); + RINOK(callbackUI->Open_Finished()) } return res; } @@ -3376,6 +3501,8 @@ HRESULT CArchiveLink::ReOpen(COpenOptions &op) if (Arcs.Size() == 0) // ??? return Open2(op, NULL); + /* if archive is multivolume (unsupported here still) + COpenCallbackImp object will exist after Open stage. */ COpenCallbackImp *openCallbackSpec = new COpenCallbackImp; CMyComPtr<IArchiveOpenCallback> openCallbackNew = openCallbackSpec; @@ -3384,18 +3511,20 @@ HRESULT CArchiveLink::ReOpen(COpenOptions &op) { FString dirPrefix, fileName; NFile::NDir::GetFullPathAndSplit(us2fs(op.filePath), dirPrefix, fileName); - openCallbackSpec->Init(dirPrefix, fileName); + RINOK(openCallbackSpec->Init2(dirPrefix, fileName)) } CInFileStream *fileStreamSpec = new CInFileStream; CMyComPtr<IInStream> stream(fileStreamSpec); if (!fileStreamSpec->Open(us2fs(op.filePath))) - return GetLastError(); + return GetLastError_noZero_HRESULT(); op.stream = stream; CArc &arc = Arcs[0]; - HRESULT res = arc.ReOpen(op); + const HRESULT res = arc.ReOpen(op, openCallbackNew); + + openCallbackSpec->ReOpenCallback = NULL; PasswordWasAsked = openCallbackSpec->PasswordWasAsked; // Password = openCallbackSpec->Password; @@ -3404,8 +3533,9 @@ HRESULT CArchiveLink::ReOpen(COpenOptions &op) return res; } -#ifndef _SFX +#ifndef Z7_SFX +bool ParseComplexSize(const wchar_t *s, UInt64 &result); bool ParseComplexSize(const wchar_t *s, UInt64 &result) { result = 0; @@ -3463,7 +3593,7 @@ static bool ParseTypeParams(const UString &s, COpenType &type) return false; } -bool ParseType(CCodecs &codecs, const UString &s, COpenType &type) +static bool ParseType(CCodecs &codecs, const UString &s, COpenType &type) { int pos2 = s.Find(L':'); @@ -3472,11 +3602,11 @@ bool ParseType(CCodecs &codecs, const UString &s, COpenType &type) if (pos2 < 0) { name = s; - pos2 = s.Len(); + pos2 = (int)s.Len(); } else { - name = s.Left(pos2); + name = s.Left((unsigned)pos2); pos2++; } @@ -3497,6 +3627,12 @@ bool ParseType(CCodecs &codecs, const UString &s, COpenType &type) type.CanReturnArc = false; type.CanReturnParser = true; } + else if (name.IsEqualTo_Ascii_NoCase("hash")) + { + // type.CanReturnArc = false; + // type.CanReturnParser = false; + type.IsHashType = true; + } else return false; } @@ -3505,17 +3641,17 @@ bool ParseType(CCodecs &codecs, const UString &s, COpenType &type) } - for (unsigned i = pos2; i < s.Len();) + for (unsigned i = (unsigned)pos2; i < s.Len();) { int next = s.Find(L':', i); if (next < 0) - next = s.Len(); - const UString name = s.Mid(i, next - i); + next = (int)s.Len(); + const UString name = s.Mid(i, (unsigned)next - i); if (name.IsEmpty()) return false; if (!ParseTypeParams(name, type)) return false; - i = next + 1; + i = (unsigned)next + 1; } return true; @@ -3524,21 +3660,36 @@ bool ParseType(CCodecs &codecs, const UString &s, COpenType &type) bool ParseOpenTypes(CCodecs &codecs, const UString &s, CObjectVector<COpenType> &types) { types.Clear(); + bool isHashType = false; for (unsigned pos = 0; pos < s.Len();) { int pos2 = s.Find(L'.', pos); if (pos2 < 0) - pos2 = s.Len(); - UString name = s.Mid(pos, pos2 - pos); + pos2 = (int)s.Len(); + UString name = s.Mid(pos, (unsigned)pos2 - pos); if (name.IsEmpty()) return false; COpenType type; if (!ParseType(codecs, name, type)) return false; + if (isHashType) + return false; + if (type.IsHashType) + isHashType = true; types.Add(type); - pos = pos2 + 1; + pos = (unsigned)pos2 + 1; } return true; } +/* +bool IsHashType(const CObjectVector<COpenType> &types) +{ + if (types.Size() != 1) + return false; + return types[0].IsHashType; +} +*/ + + #endif diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/OpenArchive.h b/3rdparty/lzma/CPP/7zip/UI/Common/OpenArchive.h index d46d69e8a8d..5c3bfe5df95 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/OpenArchive.h +++ b/3rdparty/lzma/CPP/7zip/UI/Common/OpenArchive.h @@ -1,15 +1,16 @@ // OpenArchive.h -#ifndef __OPEN_ARCHIVE_H -#define __OPEN_ARCHIVE_H +#ifndef ZIP7_INC_OPEN_ARCHIVE_H +#define ZIP7_INC_OPEN_ARCHIVE_H #include "../../../Windows/PropVariant.h" #include "ArchiveOpenCallback.h" #include "LoadCodecs.h" #include "Property.h" +#include "DirItem.h" -#ifndef _SFX +#ifndef Z7_SFX #define SUPPORT_ALT_STREAMS @@ -33,7 +34,7 @@ struct COptionalOpenProperties }; */ -#ifdef _SFX +#ifdef Z7_SFX #define OPEN_PROPS_DECL #else #define OPEN_PROPS_DECL const CObjectVector<CProperty> *props; @@ -70,6 +71,7 @@ struct COpenType bool CanReturnArc; bool CanReturnParser; + bool IsHashType; bool EachPos; // bool SkipSfxStub; @@ -88,9 +90,10 @@ struct COpenType COpenType(): FormatIndex(-1), Recursive(true), - EachPos(false), CanReturnArc(true), CanReturnParser(false), + IsHashType(false), + EachPos(false), // SkipSfxStub(true), // ExeAsUnknown(true), ZerosTailIsAllowed(false), @@ -121,7 +124,7 @@ struct COpenOptions IInStream *stream; ISequentialInStream *seqStream; IArchiveOpenCallback *callback; - COpenCallbackImp *callbackSpec; + COpenCallbackImp *callbackSpec; // it's used for SFX only OPEN_PROPS_DECL // bool openOnlySpecifiedByExtension, @@ -240,7 +243,7 @@ struct CReadArcItem bool MainIsDir; UInt32 ParentIndex; // use it, if IsAltStream - #ifndef _SFX + #ifndef Z7_SFX bool _use_baseParentFolder_mode; int _baseParentFolder; #endif @@ -251,22 +254,25 @@ struct CReadArcItem WriteToAltStreamIfColon = false; #endif - #ifndef _SFX + #ifndef Z7_SFX _use_baseParentFolder_mode = false; _baseParentFolder = -1; #endif } }; + + + class CArc { HRESULT PrepareToOpen(const COpenOptions &op, unsigned formatIndex, CMyComPtr<IInArchive> &archive); HRESULT CheckZerosTail(const COpenOptions &op, UInt64 offset); HRESULT OpenStream2(const COpenOptions &options); - #ifndef _SFX + #ifndef Z7_SFX // parts.Back() can contain alt stream name "nams:AltName" - HRESULT GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &parts) const; + HRESULT GetItem_PathToParent(UInt32 index, UInt32 parent, UStringVector &parts) const; #endif public: @@ -279,49 +285,50 @@ public: CMyComPtr<IArchiveGetRawProps> GetRawProps; CMyComPtr<IArchiveGetRootProps> GetRootProps; - CArcErrorInfo ErrorInfo; // for OK archives - CArcErrorInfo NonOpen_ErrorInfo; // ErrorInfo for mainArchive (false OPEN) + bool IsParseArc; + + bool IsTree; + bool IsReadOnly; + + bool Ask_Deleted; + bool Ask_AltStream; + bool Ask_Aux; + bool Ask_INode; + + bool IgnoreSplit; // don't try split handler UString Path; UString filePath; UString DefaultName; - int FormatIndex; // - 1 means Parser. - int SubfileIndex; - FILETIME MTime; - bool MTimeDefined; + int FormatIndex; // -1 means Parser + UInt32 SubfileIndex; // (UInt32)(Int32)-1; means no subfile + + // CFiTime MTime; + // bool MTime_Defined; + CArcTime MTime; Int64 Offset; // it's offset of start of archive inside stream that is open by Archive Handler UInt64 PhySize; // UInt64 OkPhySize; - bool PhySizeDefined; + bool PhySize_Defined; // bool OkPhySize_Defined; UInt64 FileSize; UInt64 AvailPhySize; // PhySize, but it's reduced if exceed end of file - // bool offsetDefined; - UInt64 GetEstmatedPhySize() const { return PhySizeDefined ? PhySize : FileSize; } + CArcErrorInfo ErrorInfo; // for OK archives + CArcErrorInfo NonOpen_ErrorInfo; // ErrorInfo for mainArchive (false OPEN) + + UInt64 GetEstmatedPhySize() const { return PhySize_Defined ? PhySize : FileSize; } UInt64 ArcStreamOffset; // offset of stream that is open by Archive Handler - Int64 GetGlobalOffset() const { return ArcStreamOffset + Offset; } // it's global offset of archive + Int64 GetGlobalOffset() const { return (Int64)ArcStreamOffset + Offset; } // it's global offset of archive // AString ErrorFlagsText; - bool IsParseArc; - - bool IsTree; - bool IsReadOnly; - - bool Ask_Deleted; - bool Ask_AltStream; - bool Ask_Aux; - bool Ask_INode; - - bool IgnoreSplit; // don't try split handler - // void Set_ErrorFlagsText(); CArc(): - MTimeDefined(false), + // MTime_Defined(false), IsTree(false), IsReadOnly(false), Ask_Deleted(false), @@ -333,34 +340,51 @@ public: HRESULT ReadBasicProps(IInArchive *archive, UInt64 startPos, HRESULT openRes); - // ~CArc(); - HRESULT Close() { InStream.Release(); return Archive->Close(); } - HRESULT GetItemPath(UInt32 index, UString &result) const; - HRESULT GetDefaultItemPath(UInt32 index, UString &result) const; + HRESULT GetItem_Path(UInt32 index, UString &result) const; + HRESULT GetItem_DefaultPath(UInt32 index, UString &result) const; // GetItemPath2 adds [DELETED] dir prefix for deleted items. - HRESULT GetItemPath2(UInt32 index, UString &result) const; + HRESULT GetItem_Path2(UInt32 index, UString &result) const; HRESULT GetItem(UInt32 index, CReadArcItem &item) const; - HRESULT GetItemSize(UInt32 index, UInt64 &size, bool &defined) const; - HRESULT GetItemMTime(UInt32 index, FILETIME &ft, bool &defined) const; - HRESULT IsItemAnti(UInt32 index, bool &result) const + HRESULT GetItem_Size(UInt32 index, UInt64 &size, bool &defined) const; + + /* if (GetProperty() returns vt==VT_EMPTY), this function sets + timestamp from archive file timestamp (MTime). + So (at) will be set in most cases (at.Def == true) + if (at.Prec == 0) + { + it means that (Prec == 0) was returned for (kpidMTime), + and no value was returned for (kpidTimeType). + it can mean Windows precision or unknown precision. + } + */ + HRESULT GetItem_MTime(UInt32 index, CArcTime &at) const; + + HRESULT IsItem_Anti(UInt32 index, bool &result) const { return Archive_GetItemBoolProp(Archive, index, kpidIsAnti, result); } HRESULT OpenStream(const COpenOptions &options); HRESULT OpenStreamOrFile(COpenOptions &options); - HRESULT ReOpen(const COpenOptions &options); + HRESULT ReOpen(const COpenOptions &options, IArchiveOpenCallback *openCallback_Additional); HRESULT CreateNewTailStream(CMyComPtr<IInStream> &stream); + + bool IsHashHandler(const COpenOptions &options) const + { + if (FormatIndex < 0) + return false; + return options.codecs->Formats[(unsigned)FormatIndex].Flags_HashHandler(); + } }; struct CArchiveLink @@ -397,6 +421,13 @@ struct CArchiveLink IArchiveGetRawProps *GetArchiveGetRawProps() const { return Arcs.Back().GetRawProps; } IArchiveGetRootProps *GetArchiveGetRootProps() const { return Arcs.Back().GetRootProps; } + /* + Open() opens archive and COpenOptions::callback + Open2() uses COpenCallbackImp that implements Volumes and password callback + Open3() calls Open2() and callbackUI->Open_Finished(); + Open_Strict() returns S_FALSE also in case, if there is non-open expected nested archive. + */ + HRESULT Open(COpenOptions &options); HRESULT Open2(COpenOptions &options, IOpenCallbackUI *callbackUI); HRESULT Open3(COpenOptions &options, IOpenCallbackUI *callbackUI); @@ -414,4 +445,25 @@ struct CArchiveLink bool ParseOpenTypes(CCodecs &codecs, const UString &s, CObjectVector<COpenType> &types); +// bool IsHashType(const CObjectVector<COpenType> &types); + + +struct CDirPathSortPair +{ + unsigned Len; + unsigned Index; + + void SetNumSlashes(const FChar *s); + + int Compare(const CDirPathSortPair &a) const + { + // We need sorting order where parent items will be after child items + if (Len < a.Len) return 1; + if (Len > a.Len) return -1; + if (Index < a.Index) return -1; + if (Index > a.Index) return 1; + return 0; + } +}; + #endif diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/PropIDUtils.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/PropIDUtils.cpp index dccc08b171e..ee9ff323632 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/PropIDUtils.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Common/PropIDUtils.cpp @@ -14,17 +14,23 @@ #include "PropIDUtils.h" +#ifndef Z7_SFX #define Get16(x) GetUi16(x) #define Get32(x) GetUi32(x) +#endif using namespace NWindows; -static const char g_WinAttribChars[16 + 1] = "RHS8DAdNTsLCOnE_"; +static const unsigned kNumWinAtrribFlags = 21; +static const char g_WinAttribChars[kNumWinAtrribFlags + 1] = "RHS8DAdNTsLCOIEV.X.PU"; + /* +FILE_ATTRIBUTE_ + 0 READONLY 1 HIDDEN 2 SYSTEM - +3 (Volume label - obsolete) 4 DIRECTORY 5 ARCHIVE 6 DEVICE @@ -34,14 +40,21 @@ static const char g_WinAttribChars[16 + 1] = "RHS8DAdNTsLCOnE_"; 10 REPARSE_POINT 11 COMPRESSED 12 OFFLINE -13 NOT_CONTENT_INDEXED +13 NOT_CONTENT_INDEXED (I - Win10 attrib/Explorer) 14 ENCRYPTED - -16 VIRTUAL +15 INTEGRITY_STREAM (V - ReFS Win8/Win2012) +16 VIRTUAL (reserved) +17 NO_SCRUB_DATA (X - ReFS Win8/Win2012 attrib) +18 RECALL_ON_OPEN or EA +19 PINNED +20 UNPINNED +21 STRICTLY_SEQUENTIAL +22 RECALL_ON_DATA_ACCESS */ + static const char kPosixTypes[16] = { '0', 'p', 'c', '3', 'd', '5', 'b', '7', '-', '9', 'l', 'B', 's', 'D', 'E', 'F' }; -#define MY_ATTR_CHAR(a, n, c) ((a) & (1 << (n))) ? c : '-'; +#define MY_ATTR_CHAR(a, n, c) (((a) & (1 << (n))) ? c : '-') static void ConvertPosixAttribToString(char *s, UInt32 a) throw() { @@ -52,9 +65,9 @@ static void ConvertPosixAttribToString(char *s, UInt32 a) throw() s[8 - i] = MY_ATTR_CHAR(a, i + 1, 'w'); s[9 - i] = MY_ATTR_CHAR(a, i + 0, 'x'); } - if ((a & 0x800) != 0) s[3] = ((a & (1 << 6)) ? 's' : 'S'); - if ((a & 0x400) != 0) s[6] = ((a & (1 << 3)) ? 's' : 'S'); - if ((a & 0x200) != 0) s[9] = ((a & (1 << 0)) ? 't' : 'T'); + if ((a & 0x800) != 0) s[3] = ((a & (1 << 6)) ? 's' : 'S'); // S_ISUID + if ((a & 0x400) != 0) s[6] = ((a & (1 << 3)) ? 's' : 'S'); // S_ISGID + if ((a & 0x200) != 0) s[9] = ((a & (1 << 0)) ? 't' : 'T'); // S_ISVTX s[10] = 0; a &= ~(UInt32)0xFFFF; @@ -65,36 +78,95 @@ static void ConvertPosixAttribToString(char *s, UInt32 a) throw() } } + void ConvertWinAttribToString(char *s, UInt32 wa) throw() { - for (int i = 0; i < 16; i++) - if ((wa & (1 << i)) && i != 7) - *s++ = g_WinAttribChars[i]; - *s = 0; + /* + some programs store posix attributes in high 16 bits. + p7zip - stores additional 0x8000 flag marker. + macos - stores additional 0x4000 flag marker. + info-zip - no additional marker. + */ + + const bool isPosix = ((wa & 0xF0000000) != 0); + + UInt32 posix = 0; + if (isPosix) + { + posix = wa >> 16; + wa &= (UInt32)0x3FFF; + } - // we support p7zip trick that stores posix attributes in high 16 bits, and 0x8000 flag - // we also support ZIP archives created in Unix, that store posix attributes in high 16 bits without 0x8000 flag + for (unsigned i = 0; i < kNumWinAtrribFlags; i++) + { + UInt32 flag = (1 << i); + if ((wa & flag) != 0) + { + char c = g_WinAttribChars[i]; + if (c != '.') + { + wa &= ~flag; + // if (i != 7) // we can disable N (NORMAL) printing + *s++ = c; + } + } + } - // if (wa & 0x8000) - if ((wa >> 16) != 0) + if (wa != 0) + { + *s++ = ' '; + ConvertUInt32ToHex8Digits(wa, s); + s += strlen(s); + } + + *s = 0; + + if (isPosix) { *s++ = ' '; - ConvertPosixAttribToString(s, wa >> 16); + ConvertPosixAttribToString(s, posix); } } -void ConvertPropertyToShortString(char *dest, const PROPVARIANT &prop, PROPID propID, bool full) throw() + +void ConvertPropertyToShortString2(char *dest, const PROPVARIANT &prop, PROPID propID, int level) throw() { *dest = 0; if (prop.vt == VT_FILETIME) { - FILETIME localFileTime; - if ((prop.filetime.dwHighDateTime == 0 && - prop.filetime.dwLowDateTime == 0) || - !::FileTimeToLocalFileTime(&prop.filetime, &localFileTime)) + const FILETIME &ft = prop.filetime; + unsigned ns100 = 0; + int numDigits = kTimestampPrintLevel_NTFS; + const unsigned prec = prop.wReserved1; + const unsigned ns100_Temp = prop.wReserved2; + if (prec != 0 + && prec <= k_PropVar_TimePrec_1ns + && ns100_Temp < 100 + && prop.wReserved3 == 0) + { + ns100 = ns100_Temp; + if (prec == k_PropVar_TimePrec_Unix || + prec == k_PropVar_TimePrec_DOS) + numDigits = 0; + else if (prec == k_PropVar_TimePrec_HighPrec) + numDigits = 9; + else + { + numDigits = (int)prec - (int)k_PropVar_TimePrec_Base; + if ( + // numDigits < kTimestampPrintLevel_DAY // for debuf + numDigits < kTimestampPrintLevel_SEC + ) + + numDigits = kTimestampPrintLevel_NTFS; + } + } + if (ft.dwHighDateTime == 0 && ft.dwLowDateTime == 0 && ns100 == 0) return; - ConvertFileTimeToString(localFileTime, dest, true, full); + if (level > numDigits) + level = numDigits; + ConvertUtcFileTimeToString2(ft, ns100, dest, level); return; } @@ -111,7 +183,7 @@ void ConvertPropertyToShortString(char *dest, const PROPVARIANT &prop, PROPID pr { if (prop.vt != VT_UI4) break; - UInt32 a = prop.ulVal; + const UInt32 a = prop.ulVal; /* if ((a & 0x8000) && (a & 0x7FFF) == 0) @@ -135,7 +207,7 @@ void ConvertPropertyToShortString(char *dest, const PROPVARIANT &prop, PROPID pr ConvertUInt32ToString((UInt32)(prop.uhVal.QuadPart >> 48), dest); dest += strlen(dest); *dest++ = '-'; - UInt64 low = prop.uhVal.QuadPart & (((UInt64)1 << 48) - 1); + const UInt64 low = prop.uhVal.QuadPart & (((UInt64)1 << 48) - 1); ConvertUInt64ToString(low, dest); return; } @@ -153,12 +225,30 @@ void ConvertPropertyToShortString(char *dest, const PROPVARIANT &prop, PROPID pr ConvertUInt64ToHex(v, dest + 2); return; } + + /* + case kpidDevice: + { + UInt64 v = 0; + if (prop.vt == VT_UI4) + v = prop.ulVal; + else if (prop.vt == VT_UI8) + v = (UInt64)prop.uhVal.QuadPart; + else + break; + ConvertUInt32ToString(MY_dev_major(v), dest); + dest += strlen(dest); + *dest++ = ','; + ConvertUInt32ToString(MY_dev_minor(v), dest); + return; + } + */ } ConvertPropVariantToShortString(prop, dest); } -void ConvertPropertyToString(UString &dest, const PROPVARIANT &prop, PROPID propID, bool full) +void ConvertPropertyToString2(UString &dest, const PROPVARIANT &prop, PROPID propID, int level) { if (prop.vt == VT_BSTR) { @@ -166,22 +256,21 @@ void ConvertPropertyToString(UString &dest, const PROPVARIANT &prop, PROPID prop return; } char temp[64]; - ConvertPropertyToShortString(temp, prop, propID, full); - dest.SetFromAscii(temp); + ConvertPropertyToShortString2(temp, prop, propID, level); + dest = temp; } +#ifndef Z7_SFX + static inline unsigned GetHex(unsigned v) { return (v < 10) ? ('0' + v) : ('A' + (v - 10)); } -#ifndef _SFX - static inline void AddHexToString(AString &res, unsigned v) { res += (char)GetHex(v >> 4); res += (char)GetHex(v & 0xF); - res += ' '; } /* @@ -226,6 +315,14 @@ struct CSecID2Name const char *sz; }; +static int FindPairIndex(const CSecID2Name * pairs, unsigned num, UInt32 id) +{ + for (unsigned i = 0; i < num; i++) + if (pairs[i].n == id) + return (int)i; + return -1; +} + static const CSecID2Name sid_32_Names[] = { { 544, "Administrators" }, @@ -290,52 +387,52 @@ static void ParseSid(AString &s, const Byte *p, UInt32 lim, UInt32 &sidSize) s += "ERROR"; return; } - UInt32 rev = p[0]; + const UInt32 rev = p[0]; if (rev != 1) { s += "UNSUPPORTED"; return; } - UInt32 num = p[1]; + const UInt32 num = p[1]; if (8 + num * 4 > lim) { s += "ERROR"; return; } sidSize = 8 + num * 4; - UInt32 authority = GetBe32(p + 4); + const UInt32 authority = GetBe32(p + 4); if (p[2] == 0 && p[3] == 0 && authority == 5 && num >= 1) { - UInt32 v0 = Get32(p + 8); - if (v0 < ARRAY_SIZE(sidNames)) + const UInt32 v0 = Get32(p + 8); + if (v0 < Z7_ARRAY_SIZE(sidNames)) { s += sidNames[v0]; return; } if (v0 == 32 && num == 2) { - UInt32 v1 = Get32(p + 12); - for (unsigned i = 0; i < ARRAY_SIZE(sid_32_Names); i++) - if (sid_32_Names[i].n == v1) - { - s += sid_32_Names[i].sz; - return; - } + const UInt32 v1 = Get32(p + 12); + const int index = FindPairIndex(sid_32_Names, Z7_ARRAY_SIZE(sid_32_Names), v1); + if (index >= 0) + { + s += sid_32_Names[(unsigned)index].sz; + return; + } } if (v0 == 21 && num == 5) { UInt32 v4 = Get32(p + 8 + 4 * 4); - for (unsigned i = 0; i < ARRAY_SIZE(sid_21_Names); i++) - if (sid_21_Names[i].n == v4) - { - s += sid_21_Names[i].sz; - return; - } + const int index = FindPairIndex(sid_21_Names, Z7_ARRAY_SIZE(sid_21_Names), v4); + if (index >= 0) + { + s += sid_21_Names[(unsigned)index].sz; + return; + } } if (v0 == 80 && num == 6) { - for (unsigned i = 0; i < ARRAY_SIZE(services_to_name); i++) + for (unsigned i = 0; i < Z7_ARRAY_SIZE(services_to_name); i++) { const CServicesToName &sn = services_to_name[i]; int j; @@ -349,13 +446,9 @@ static void ParseSid(AString &s, const Byte *p, UInt32 lim, UInt32 &sidSize) } } - char sz[16]; s += "S-1-"; if (p[2] == 0 && p[3] == 0) - { - ConvertUInt32ToString(authority, sz); - s += sz; - } + s.Add_UInt32(authority); else { s += "0x"; @@ -364,9 +457,8 @@ static void ParseSid(AString &s, const Byte *p, UInt32 lim, UInt32 &sidSize) } for (UInt32 i = 0; i < num; i++) { - s += '-'; - ConvertUInt32ToString(Get32(p + 8 + i * 4), sz); - s += sz; + s.Add_Minus(); + s.Add_UInt32(Get32(p + 8 + i * 4)); } } @@ -381,20 +473,13 @@ static void ParseOwner(AString &s, const Byte *p, UInt32 size, UInt32 pos) ParseSid(s, p + pos, size - pos, sidSize); } -static void AddUInt32ToString(AString &s, UInt32 val) -{ - char sz[16]; - ConvertUInt32ToString(val, sz); - s += sz; -} - static void ParseAcl(AString &s, const Byte *p, UInt32 size, const char *strName, UInt32 flags, UInt32 offset) { - UInt32 control = Get16(p + 2); + const UInt32 control = Get16(p + 2); if ((flags & control) == 0) return; - UInt32 pos = Get32(p + offset); - s += ' '; + const UInt32 pos = Get32(p + offset); + s.Add_Space(); s += strName; if (pos >= size) return; @@ -404,8 +489,8 @@ static void ParseAcl(AString &s, const Byte *p, UInt32 size, const char *strName return; if (Get16(p) != 2) // revision return; - UInt32 num = Get32(p + 4); - AddUInt32ToString(s, num); + const UInt32 num = Get32(p + 4); + s.Add_UInt32(num); /* UInt32 aclSize = Get16(p + 2); @@ -428,7 +513,7 @@ static void ParseAcl(AString &s, const Byte *p, UInt32 size, const char *strName size -= 8; UInt32 sidSize = 0; - s += ' '; + s.Add_Space(); ParseSid(s, p, size, sidSize); if (sidSize == 0) return; @@ -441,11 +526,16 @@ static void ParseAcl(AString &s, const Byte *p, UInt32 size, const char *strName */ } +/* #define MY_SE_OWNER_DEFAULTED (0x0001) #define MY_SE_GROUP_DEFAULTED (0x0002) +*/ #define MY_SE_DACL_PRESENT (0x0004) +/* #define MY_SE_DACL_DEFAULTED (0x0008) +*/ #define MY_SE_SACL_PRESENT (0x0010) +/* #define MY_SE_SACL_DEFAULTED (0x0020) #define MY_SE_DACL_AUTO_INHERIT_REQ (0x0100) #define MY_SE_SACL_AUTO_INHERIT_REQ (0x0200) @@ -455,6 +545,7 @@ static void ParseAcl(AString &s, const Byte *p, UInt32 size, const char *strName #define MY_SE_SACL_PROTECTED (0x2000) #define MY_SE_RM_CONTROL_VALID (0x4000) #define MY_SE_SELF_RELATIVE (0x8000) +*/ void ConvertNtSecureToString(const Byte *data, UInt32 size, AString &s) { @@ -470,12 +561,12 @@ void ConvertNtSecureToString(const Byte *data, UInt32 size, AString &s) return; } ParseOwner(s, data, size, Get32(data + 4)); - s += ' '; + s.Add_Space(); ParseOwner(s, data, size, Get32(data + 8)); ParseAcl(s, data, size, "s:", MY_SE_SACL_PRESENT, 12); ParseAcl(s, data, size, "d:", MY_SE_DACL_PRESENT, 16); - s += ' '; - AddUInt32ToString(s, size); + s.Add_Space(); + s.Add_UInt32(size); // s += '\n'; // s += Data_To_Hex(data, size); } @@ -489,26 +580,26 @@ static bool CheckSid(const Byte *data, UInt32 size, UInt32 pos) throw() size -= pos; if (size < 8) return false; - UInt32 rev = data[pos]; + const UInt32 rev = data[pos]; if (rev != 1) return false; - UInt32 num = data[pos + 1]; + const UInt32 num = data[pos + 1]; return (8 + num * 4 <= size); } static bool CheckAcl(const Byte *p, UInt32 size, UInt32 flags, UInt32 offset) throw() { - UInt32 control = Get16(p + 2); + const UInt32 control = Get16(p + 2); if ((flags & control) == 0) return true; - UInt32 pos = Get32(p + offset); + const UInt32 pos = Get32(p + offset); if (pos >= size) return false; p += pos; size -= pos; if (size < 8) return false; - UInt32 aclSize = Get16(p + 2); + const UInt32 aclSize = Get16(p + 2); return (aclSize <= size); } @@ -529,45 +620,121 @@ bool CheckNtSecure(const Byte *data, UInt32 size) throw() #endif + + +// IO_REPARSE_TAG_* + +static const CSecID2Name k_ReparseTags[] = +{ + { 0xA0000003, "MOUNT_POINT" }, + { 0xC0000004, "HSM" }, + { 0x80000005, "DRIVE_EXTENDER" }, + { 0x80000006, "HSM2" }, + { 0x80000007, "SIS" }, + { 0x80000008, "WIM" }, + { 0x80000009, "CSV" }, + { 0x8000000A, "DFS" }, + { 0x8000000B, "FILTER_MANAGER" }, + { 0xA000000C, "SYMLINK" }, + { 0xA0000010, "IIS_CACHE" }, + { 0x80000012, "DFSR" }, + { 0x80000013, "DEDUP" }, + { 0xC0000014, "APPXSTRM" }, + { 0x80000014, "NFS" }, + { 0x80000015, "FILE_PLACEHOLDER" }, + { 0x80000016, "DFM" }, + { 0x80000017, "WOF" }, + { 0x80000018, "WCI" }, + { 0x8000001B, "APPEXECLINK" }, + { 0xA000001D, "LX_SYMLINK" }, + { 0x80000023, "AF_UNIX" }, + { 0x80000024, "LX_FIFO" }, + { 0x80000025, "LX_CHR" }, + { 0x80000026, "LX_BLK" } +}; + bool ConvertNtReparseToString(const Byte *data, UInt32 size, UString &s) { s.Empty(); NFile::CReparseAttr attr; + if (attr.Parse(data, size)) { - if (!attr.IsSymLink()) - s.AddAscii("Junction: "); - s += attr.GetPath(); - if (!attr.IsOkNamePair()) + if (attr.IsSymLink_WSL()) { - s.AddAscii(" : "); - s += attr.PrintName; + s += "WSL: "; + s += attr.GetPath(); } + else + { + if (!attr.IsSymLink_Win()) + s += "Junction: "; + s += attr.GetPath(); + if (s.IsEmpty()) + s += "Link: "; + if (!attr.IsOkNamePair()) + { + s += " : "; + s += attr.PrintName; + } + } + if (attr.MinorError) + s += " : MINOR_ERROR"; return true; + // s += " "; // for debug } if (size < 8) return false; - UInt32 tag = Get32(data); - UInt32 len = Get16(data + 4); + const UInt32 tag = Get32(data); + const UInt32 len = Get16(data + 4); if (len + 8 > size) return false; if (Get16(data + 6) != 0) // padding return false; - char hex[16]; - ConvertUInt32ToHex8Digits(tag, hex); - s.AddAscii(hex); - s.Add_Space(); + /* + #define my_IO_REPARSE_TAG_DEDUP (0x80000013L) + if (tag == my_IO_REPARSE_TAG_DEDUP) + { + } + */ + + { + const int index = FindPairIndex(k_ReparseTags, Z7_ARRAY_SIZE(k_ReparseTags), tag); + if (index >= 0) + s += k_ReparseTags[(unsigned)index].sz; + else + { + s += "REPARSE:"; + char hex[16]; + ConvertUInt32ToHex8Digits(tag, hex); + s += hex; + } + } - data += 8; + s += ":"; + s.Add_UInt32(len); - for (UInt32 i = 0; i < len; i++) + if (len != 0) { - unsigned b = ((const Byte *)data)[i]; - s += (wchar_t)GetHex((b >> 4) & 0xF); - s += (wchar_t)GetHex(b & 0xF); + s.Add_Space(); + + data += 8; + + for (UInt32 i = 0; i < len; i++) + { + if (i >= 16) + { + s += "..."; + break; + } + const unsigned b = data[i]; + s += (char)GetHex((b >> 4) & 0xF); + s += (char)GetHex(b & 0xF); + } } + return true; } diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/PropIDUtils.h b/3rdparty/lzma/CPP/7zip/UI/Common/PropIDUtils.h index 1dea321e9ac..6df1e94c37d 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/PropIDUtils.h +++ b/3rdparty/lzma/CPP/7zip/UI/Common/PropIDUtils.h @@ -1,17 +1,17 @@ // PropIDUtils.h -#ifndef __PROPID_UTILS_H -#define __PROPID_UTILS_H +#ifndef ZIP7_INC_PROPID_UTILS_H +#define ZIP7_INC_PROPID_UTILS_H #include "../../../Common/MyString.h" // provide at least 64 bytes for buffer including zero-end -void ConvertPropertyToShortString(char *dest, const PROPVARIANT &propVariant, PROPID propID, bool full = true) throw(); -void ConvertPropertyToString(UString &dest, const PROPVARIANT &propVariant, PROPID propID, bool full = true); +void ConvertPropertyToShortString2(char *dest, const PROPVARIANT &propVariant, PROPID propID, int level = 0) throw(); +void ConvertPropertyToString2(UString &dest, const PROPVARIANT &propVariant, PROPID propID, int level = 0); bool ConvertNtReparseToString(const Byte *data, UInt32 size, UString &s); void ConvertNtSecureToString(const Byte *data, UInt32 size, AString &s); -bool CheckNtSecure(const Byte *data, UInt32 size) throw();; +bool CheckNtSecure(const Byte *data, UInt32 size) throw(); void ConvertWinAttribToString(char *s, UInt32 wa) throw(); diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/Property.h b/3rdparty/lzma/CPP/7zip/UI/Common/Property.h index 8b57a2a648a..04628098916 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/Property.h +++ b/3rdparty/lzma/CPP/7zip/UI/Common/Property.h @@ -1,7 +1,7 @@ // Property.h -#ifndef __7Z_PROPERTY_H -#define __7Z_PROPERTY_H +#ifndef ZIP7_INC_7Z_PROPERTY_H +#define ZIP7_INC_7Z_PROPERTY_H #include "../../../Common/MyString.h" diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/SetProperties.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/SetProperties.cpp index c3de5d5a323..5e15d9c09fb 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/SetProperties.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Common/SetProperties.cpp @@ -18,7 +18,7 @@ using namespace NCOM; static void ParseNumberString(const UString &s, NCOM::CPropVariant &prop) { const wchar_t *end; - UInt64 result = ConvertStringToUInt64(s, &end); + const UInt64 result = ConvertStringToUInt64(s, &end); if (*end != 0 || s.IsEmpty()) prop = s; else if (result <= (UInt32)0xFFFFFFFF) @@ -27,18 +27,33 @@ static void ParseNumberString(const UString &s, NCOM::CPropVariant &prop) prop = result; } + +struct CPropPropetiesVector +{ + CPropVariant *values; + CPropPropetiesVector(unsigned num) + { + values = new CPropVariant[num]; + } + ~CPropPropetiesVector() + { + delete []values; + } +}; + + HRESULT SetProperties(IUnknown *unknown, const CObjectVector<CProperty> &properties) { if (properties.IsEmpty()) return S_OK; - CMyComPtr<ISetProperties> setProperties; - unknown->QueryInterface(IID_ISetProperties, (void **)&setProperties); + Z7_DECL_CMyComPtr_QI_FROM( + ISetProperties, + setProperties, unknown) if (!setProperties) return S_OK; UStringVector realNames; - CPropVariant *values = new CPropVariant[properties.Size()]; - try + CPropPropetiesVector values(properties.Size()); { unsigned i; for (i = 0; i < properties.Size(); i++) @@ -50,7 +65,7 @@ HRESULT SetProperties(IUnknown *unknown, const CObjectVector<CProperty> &propert { if (!name.IsEmpty()) { - wchar_t c = name.Back(); + const wchar_t c = name.Back(); if (c == L'-') propVariant = false; else if (c == L'+') @@ -62,19 +77,12 @@ HRESULT SetProperties(IUnknown *unknown, const CObjectVector<CProperty> &propert else ParseNumberString(property.Value, propVariant); realNames.Add(name); - values[i] = propVariant; + values.values[i] = propVariant; } CRecordVector<const wchar_t *> names; for (i = 0; i < realNames.Size(); i++) names.Add((const wchar_t *)realNames[i]); - RINOK(setProperties->SetProperties(&names.Front(), values, names.Size())); - } - catch(...) - { - delete []values; - throw; + return setProperties->SetProperties(&names.Front(), values.values, names.Size()); } - delete []values; - return S_OK; } diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/SetProperties.h b/3rdparty/lzma/CPP/7zip/UI/Common/SetProperties.h index 892f1a21037..0676c45daa8 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/SetProperties.h +++ b/3rdparty/lzma/CPP/7zip/UI/Common/SetProperties.h @@ -1,7 +1,7 @@ // SetProperties.h -#ifndef __SETPROPERTIES_H -#define __SETPROPERTIES_H +#ifndef ZIP7_INC_SETPROPERTIES_H +#define ZIP7_INC_SETPROPERTIES_H #include "Property.h" diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/SortUtils.h b/3rdparty/lzma/CPP/7zip/UI/Common/SortUtils.h index 8e42e06827a..07aa24d22e9 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/SortUtils.h +++ b/3rdparty/lzma/CPP/7zip/UI/Common/SortUtils.h @@ -1,7 +1,7 @@ // SortUtils.h -#ifndef __SORT_UTLS_H -#define __SORT_UTLS_H +#ifndef ZIP7_INC_SORT_UTLS_H +#define ZIP7_INC_SORT_UTLS_H #include "../../../Common/MyString.h" diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/StdAfx.h b/3rdparty/lzma/CPP/7zip/UI/Common/StdAfx.h index 2854ff3e935..035267ccd02 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/StdAfx.h +++ b/3rdparty/lzma/CPP/7zip/UI/Common/StdAfx.h @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../../Common/Common.h" #endif diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/TempFiles.h b/3rdparty/lzma/CPP/7zip/UI/Common/TempFiles.h index 4099e655898..dd4ac2038d0 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/TempFiles.h +++ b/3rdparty/lzma/CPP/7zip/UI/Common/TempFiles.h @@ -1,7 +1,7 @@ // TempFiles.h -#ifndef __TEMP_FILES_H -#define __TEMP_FILES_H +#ifndef ZIP7_INC_TEMP_FILES_H +#define ZIP7_INC_TEMP_FILES_H #include "../../../Common/MyString.h" diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/Update.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/Update.cpp index 0db4a87f0d4..27625aebbe4 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/Update.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Common/Update.cpp @@ -2,9 +2,10 @@ #include "StdAfx.h" +// #include <stdio.h> + #include "Update.h" -#include "../../../Common/IntToString.h" #include "../../../Common/StringConvert.h" #include "../../../Windows/DLL.h" @@ -17,6 +18,8 @@ #include "../../Common/FileStreams.h" #include "../../Common/LimitedStreams.h" +#include "../../Common/MultiOutStream.h" +#include "../../Common/StreamUtils.h" #include "../../Compress/CopyCoder.h" @@ -30,17 +33,21 @@ #include "TempFiles.h" #include "UpdateCallback.h" -static const char *kUpdateIsNotSupoorted = +static const char * const kUpdateIsNotSupoorted = "update operations are not supported for this archive"; +static const char * const kUpdateIsNotSupported_MultiVol = + "Updating for multivolume archives is not implemented"; + using namespace NWindows; using namespace NCOM; using namespace NFile; using namespace NDir; using namespace NName; -static CFSTR kTempFolderPrefix = FTEXT("7zE"); - +#ifdef _WIN32 +static CFSTR const kTempFolderPrefix = FTEXT("7zE"); +#endif void CUpdateErrorInfo::SetFromLastError(const char *message) { @@ -55,228 +62,55 @@ HRESULT CUpdateErrorInfo::SetFromLastError(const char *message, const FString &f return Get_HRESULT_Error(); } -static bool DeleteEmptyFolderAndEmptySubFolders(const FString &path) +HRESULT CUpdateErrorInfo::SetFromError_DWORD(const char *message, const FString &fileName, DWORD error) { - NFind::CFileInfo fileInfo; - FString pathPrefix = path + FCHAR_PATH_SEPARATOR; - { - NFind::CEnumerator enumerator(pathPrefix + FCHAR_ANY_MASK); - while (enumerator.Next(fileInfo)) - { - if (fileInfo.IsDir()) - if (!DeleteEmptyFolderAndEmptySubFolders(pathPrefix + fileInfo.Name)) - return false; - } - } - /* - // we don't need clear read-only for folders - if (!MySetFileAttributes(path, 0)) - return false; - */ - return RemoveDir(path); + Message = message; + FileNames.Add(fileName); + SystemError = error; + return Get_HRESULT_Error(); } using namespace NUpdateArchive; -class COutMultiVolStream: - public IOutStream, - public CMyUnknownImp +struct CMultiOutStream_Rec { - unsigned _streamIndex; // required stream - UInt64 _offsetPos; // offset from start of _streamIndex index - UInt64 _absPos; - UInt64 _length; - - struct CAltStreamInfo - { - COutFileStream *StreamSpec; - CMyComPtr<IOutStream> Stream; - FString Name; - UInt64 Pos; - UInt64 RealSize; - }; - CObjectVector<CAltStreamInfo> Streams; -public: - // CMyComPtr<IArchiveUpdateCallback2> VolumeCallback; - CRecordVector<UInt64> Sizes; - FString Prefix; - CTempFiles *TempFiles; - - void Init() - { - _streamIndex = 0; - _offsetPos = 0; - _absPos = 0; - _length = 0; - } - - bool SetMTime(const FILETIME *mTime); - HRESULT Close(); - - UInt64 GetSize() const { return _length; } - - MY_UNKNOWN_IMP1(IOutStream) - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - STDMETHOD(SetSize)(UInt64 newSize); + CMultiOutStream *Spec; + CMyComPtr<IOutStream> Ref; }; -// static NSynchronization::CCriticalSection g_TempPathsCS; - -HRESULT COutMultiVolStream::Close() +struct CMultiOutStream_Bunch { - HRESULT res = S_OK; - FOR_VECTOR (i, Streams) - { - COutFileStream *s = Streams[i].StreamSpec; - if (s) - { - HRESULT res2 = s->Close(); - if (res2 != S_OK) - res = res2; - } - } - return res; -} - -bool COutMultiVolStream::SetMTime(const FILETIME *mTime) -{ - bool res = true; - FOR_VECTOR (i, Streams) - { - COutFileStream *s = Streams[i].StreamSpec; - if (s) - if (!s->SetMTime(mTime)) - res = false; - } - return res; -} - -STDMETHODIMP COutMultiVolStream::Write(const void *data, UInt32 size, UInt32 *processedSize) -{ - if (processedSize != NULL) - *processedSize = 0; - while (size > 0) + CObjectVector<CMultiOutStream_Rec> Items; + + HRESULT Destruct() { - if (_streamIndex >= Streams.Size()) + HRESULT hres = S_OK; + FOR_VECTOR (i, Items) { - CAltStreamInfo altStream; - - FChar temp[16]; - ConvertUInt32ToString(_streamIndex + 1, temp); - FString name = temp; - while (name.Len() < 3) - name.InsertAtFront(FTEXT('0')); - name.Insert(0, Prefix); - altStream.StreamSpec = new COutFileStream; - altStream.Stream = altStream.StreamSpec; - if (!altStream.StreamSpec->Create(name, false)) - return ::GetLastError(); + CMultiOutStream_Rec &rec = Items[i]; + if (rec.Ref) { - // NSynchronization::CCriticalSectionLock lock(g_TempPathsCS); - TempFiles->Paths.Add(name); + const HRESULT hres2 = rec.Spec->Destruct(); + if (hres == S_OK) + hres = hres2; } - - altStream.Pos = 0; - altStream.RealSize = 0; - altStream.Name = name; - Streams.Add(altStream); - continue; } - CAltStreamInfo &altStream = Streams[_streamIndex]; - - unsigned index = _streamIndex; - if (index >= Sizes.Size()) - index = Sizes.Size() - 1; - UInt64 volSize = Sizes[index]; - - if (_offsetPos >= volSize) - { - _offsetPos -= volSize; - _streamIndex++; - continue; - } - if (_offsetPos != altStream.Pos) - { - // CMyComPtr<IOutStream> outStream; - // RINOK(altStream.Stream.QueryInterface(IID_IOutStream, &outStream)); - RINOK(altStream.Stream->Seek(_offsetPos, STREAM_SEEK_SET, NULL)); - altStream.Pos = _offsetPos; - } - - UInt32 curSize = (UInt32)MyMin((UInt64)size, volSize - altStream.Pos); - UInt32 realProcessed; - RINOK(altStream.Stream->Write(data, curSize, &realProcessed)); - data = (void *)((Byte *)data + realProcessed); - size -= realProcessed; - altStream.Pos += realProcessed; - _offsetPos += realProcessed; - _absPos += realProcessed; - if (_absPos > _length) - _length = _absPos; - if (_offsetPos > altStream.RealSize) - altStream.RealSize = _offsetPos; - if (processedSize != NULL) - *processedSize += realProcessed; - if (altStream.Pos == volSize) - { - _streamIndex++; - _offsetPos = 0; - } - if (realProcessed == 0 && curSize != 0) - return E_FAIL; - break; + Items.Clear(); + return hres; } - return S_OK; -} -STDMETHODIMP COutMultiVolStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) -{ - if (seekOrigin >= 3) - return STG_E_INVALIDFUNCTION; - switch (seekOrigin) - { - case STREAM_SEEK_SET: _absPos = offset; break; - case STREAM_SEEK_CUR: _absPos += offset; break; - case STREAM_SEEK_END: _absPos = _length + offset; break; - } - _offsetPos = _absPos; - if (newPosition != NULL) - *newPosition = _absPos; - _streamIndex = 0; - return S_OK; -} - -STDMETHODIMP COutMultiVolStream::SetSize(UInt64 newSize) -{ - unsigned i = 0; - while (i < Streams.Size()) - { - CAltStreamInfo &altStream = Streams[i++]; - if ((UInt64)newSize < altStream.RealSize) - { - RINOK(altStream.Stream->SetSize(newSize)); - altStream.RealSize = newSize; - break; - } - newSize -= altStream.RealSize; - } - while (i < Streams.Size()) + void DisableDeletion() { + FOR_VECTOR (i, Items) { - CAltStreamInfo &altStream = Streams.Back(); - altStream.Stream.Release(); - DeleteFileAlways(altStream.Name); + CMultiOutStream_Rec &rec = Items[i]; + if (rec.Ref) + rec.Spec->NeedDelete = false; } - Streams.DeleteBack(); } - _offsetPos = _absPos; - _streamIndex = 0; - _length = newSize; - return S_OK; -} +}; + void CArchivePath::ParseFromPath(const UString &path, EArcNameMode mode) { @@ -286,29 +120,27 @@ void CArchivePath::ParseFromPath(const UString &path, EArcNameMode mode) if (mode == k_ArcNameMode_Add) return; - if (mode == k_ArcNameMode_Exact) - { - BaseExtension.Empty(); - return; - } - int dotPos = Name.ReverseFind_Dot(); - if (dotPos < 0) - return; - if ((unsigned)dotPos == Name.Len() - 1) - { - Name.DeleteBack(); - BaseExtension.Empty(); - return; - } - const UString ext = Name.Ptr(dotPos + 1); - if (BaseExtension.IsEqualTo_NoCase(ext)) + if (mode != k_ArcNameMode_Exact) { - BaseExtension = ext; - Name.DeleteFrom(dotPos); + int dotPos = Name.ReverseFind_Dot(); + if (dotPos < 0) + return; + if ((unsigned)dotPos == Name.Len() - 1) + Name.DeleteBack(); + else + { + const UString ext = Name.Ptr((unsigned)(dotPos + 1)); + if (BaseExtension.IsEqualTo_NoCase(ext)) + { + BaseExtension = ext; + Name.DeleteFrom((unsigned)dotPos); + return; + } + } } - else - BaseExtension.Empty(); + + BaseExtension.Empty(); } UString CArchivePath::GetFinalPath() const @@ -316,7 +148,7 @@ UString CArchivePath::GetFinalPath() const UString path = GetPathWithoutExt(); if (!BaseExtension.IsEmpty()) { - path += L'.'; + path.Add_Dot(); path += BaseExtension; } return path; @@ -325,9 +157,10 @@ UString CArchivePath::GetFinalPath() const UString CArchivePath::GetFinalVolPath() const { UString path = GetPathWithoutExt(); + // if BaseExtension is empty, we must ignore VolExtension also. if (!BaseExtension.IsEmpty()) { - path += L'.'; + path.Add_Dot(); path += VolExtension; } return path; @@ -339,17 +172,17 @@ FString CArchivePath::GetTempPath() const path += us2fs(Name); if (!BaseExtension.IsEmpty()) { - path += FTEXT('.'); + path.Add_Dot(); path += us2fs(BaseExtension); } - path.AddAscii(".tmp"); + path += ".tmp"; path += TempPostfix; return path; } -static const wchar_t *kDefaultArcType = L"7z"; -static const wchar_t *kDefaultArcExt = L"7z"; -static const char *kSFXExtension = +static const char * const kDefaultArcType = "7z"; +static const char * const kDefaultArcExt = "7z"; +static const char * const kSFXExtension = #ifdef _WIN32 "exe"; #else @@ -391,14 +224,14 @@ bool CUpdateOptions::SetArcPath(const CCodecs *codecs, const UString &arcPath) } else { - const CArcInfoEx &arcInfo = codecs->Formats[formatIndex]; + const CArcInfoEx &arcInfo = codecs->Formats[(unsigned)formatIndex]; if (!arcInfo.UpdateEnabled) return false; typeExt = arcInfo.GetMainExt(); } UString ext = typeExt; if (SfxMode) - ext.SetFromAscii(kSFXExtension); + ext = kSFXExtension; ArchivePath.BaseExtension = ext; ArchivePath.VolExtension = typeExt; ArchivePath.ParseFromPath(arcPath, ArcNameMode); @@ -412,19 +245,43 @@ bool CUpdateOptions::SetArcPath(const CCodecs *codecs, const UString &arcPath) return true; } -struct CUpdateProduceCallbackImp: public IUpdateProduceCallback + +struct CUpdateProduceCallbackImp Z7_final: public IUpdateProduceCallback { const CObjectVector<CArcItem> *_arcItems; + CDirItemsStat *_stat; IUpdateCallbackUI *_callback; - CUpdateProduceCallbackImp(const CObjectVector<CArcItem> *a, - IUpdateCallbackUI *callback): _arcItems(a), _callback(callback) {} - virtual HRESULT ShowDeleteFile(unsigned arcIndex); + CUpdateProduceCallbackImp( + const CObjectVector<CArcItem> *a, + CDirItemsStat *stat, + IUpdateCallbackUI *callback): + _arcItems(a), + _stat(stat), + _callback(callback) {} + + virtual HRESULT ShowDeleteFile(unsigned arcIndex) Z7_override; }; + HRESULT CUpdateProduceCallbackImp::ShowDeleteFile(unsigned arcIndex) { const CArcItem &ai = (*_arcItems)[arcIndex]; + { + CDirItemsStat &stat = *_stat; + if (ai.IsDir) + stat.NumDirs++; + else if (ai.IsAltStream) + { + stat.NumAltStreams++; + stat.AltStreamsSize += ai.Size; + } + else + { + stat.NumFiles++; + stat.FilesSize += ai.Size; + } + } return _callback->ShowDeleteFile(ai.Name, ai.IsDir); } @@ -485,6 +342,8 @@ bool CRenamePair::GetNewPath(bool isFolder, const UString &src, UString &dest) c int FindAltStreamColon_in_Path(const wchar_t *path); #endif + + static HRESULT Compress( const CUpdateOptions &options, bool isUpdatingItself, @@ -497,6 +356,7 @@ static HRESULT Compress( const CDirItems &dirItems, const CDirItem *parentDirItem, CTempFiles &tempFiles, + CMultiOutStream_Bunch &multiStreams, CUpdateErrorInfo &errorInfo, IUpdateCallbackUI *callback, CFinishArchiveStat &st) @@ -516,28 +376,63 @@ static HRESULT Compress( } else { - RINOK(codecs->CreateOutArchive(formatIndex, outArchive)); + RINOK(codecs->CreateOutArchive((unsigned)formatIndex, outArchive)) - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS { CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo; outArchive.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo); if (setCompressCodecsInfo) { - RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecs)); + RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecs)) } } #endif } - if (outArchive == 0) + if (!outArchive) throw kUpdateIsNotSupoorted; - + + // we need to set properties to get fileTimeType. + RINOK(SetProperties(outArchive, options.MethodMode.Properties)) + NFileTimeType::EEnum fileTimeType; { + /* + how we compare file_in_archive::MTime with dirItem.MTime + for GetUpdatePairInfoList(): + + if (kpidMTime is not defined), external MTime of archive is used. + + before 22.00: + if (kpidTimeType is defined) + { + kpidTimeType is used as precision. + (kpidTimeType > kDOS) is not allowed. + } + else GetFileTimeType() value is used as precision. + + 22.00: + if (kpidMTime is defined) + { + if (kpidMTime::precision != 0), then kpidMTime::precision is used as precision. + else + { + if (kpidTimeType is defined), kpidTimeType is used as precision. + else GetFileTimeType() value is used as precision. + } + } + else external MTime of archive is used as precision. + */ + UInt32 value; - RINOK(outArchive->GetFileTimeType(&value)); + RINOK(outArchive->GetFileTimeType(&value)) + + // we support any future fileType here. + fileTimeType = (NFileTimeType::EEnum)value; + /* + old 21.07 code: switch (value) { case NFileTimeType::kWindows: @@ -548,13 +443,28 @@ static HRESULT Compress( default: return E_FAIL; } + */ } + // bool noTimestampExpected = false; { - const CArcInfoEx &arcInfo = codecs->Formats[formatIndex]; + const CArcInfoEx &arcInfo = codecs->Formats[(unsigned)formatIndex]; + + // if (arcInfo.Flags_KeepName()) noTimestampExpected = true; + if (arcInfo.Is_Xz() || + arcInfo.Is_BZip2()) + { + /* 7-zip before 22.00 returns NFileTimeType::kUnix for xz and bzip2, + but we want to set timestamp without reduction to unix. */ + // noTimestampExpected = true; + fileTimeType = NFileTimeType::kNotDefined; // it means not defined + } + if (options.AltStreams.Val && !arcInfo.Flags_AltStreams()) return E_NOTIMPL; - if (options.NtSecurity.Val && !arcInfo.Flags_NtSecure()) + if (options.NtSecurity.Val && !arcInfo.Flags_NtSecurity()) + return E_NOTIMPL; + if (options.DeleteAfterCompressing && arcInfo.Flags_HashHandler()) return E_NOTIMPL; } @@ -562,6 +472,8 @@ static HRESULT Compress( UStringVector newNames; + CArcToDoStat stat2; + if (options.RenamePairs.Size() != 0) { FOR_VECTOR (i, arcItems) @@ -587,7 +499,7 @@ static HRESULT Compress( int colonPos = FindAltStreamColon_in_Path(ai.Name); if (colonPos >= 0) { - UString mainName = ai.Name.Left(colonPos); + UString mainName = ai.Name.Left((unsigned)colonPos); /* actually we must improve that code to support cases with folder renaming like: rn arc dir1\ dir2\ @@ -595,8 +507,8 @@ static HRESULT Compress( if (rp.GetNewPath(false, mainName, dest)) { needRename = true; - dest += L':'; - dest += ai.Name.Ptr(colonPos + 1); + dest += ':'; + dest += ai.Name.Ptr((unsigned)(colonPos + 1)); break; } } @@ -610,8 +522,8 @@ static HRESULT Compress( if (needRename) { up2.NewProps = true; - RINOK(arc->IsItemAnti(i, up2.IsAnti)); - up2.NewNameIndex = newNames.Add(dest); + RINOK(arc->IsItem_Anti(i, up2.IsAnti)) + up2.NewNameIndex = (int)newNames.Add(dest); } updatePairs2.Add(up2); } @@ -620,23 +532,97 @@ static HRESULT Compress( { CRecordVector<CUpdatePair> updatePairs; GetUpdatePairInfoList(dirItems, arcItems, fileTimeType, updatePairs); // must be done only once!!! - CUpdateProduceCallbackImp upCallback(&arcItems, callback); + CUpdateProduceCallbackImp upCallback(&arcItems, &stat2.DeleteData, callback); UpdateProduce(updatePairs, actionSet, updatePairs2, isUpdatingItself ? &upCallback : NULL); } { - UInt32 numItems = 0; FOR_VECTOR (i, updatePairs2) - if (updatePairs2[i].NewData) - numItems++; - RINOK(callback->SetNumItems(numItems)); + { + const CUpdatePair2 &up = updatePairs2[i]; + + // 17.01: anti-item is (up.NewData && (p.UseArcProps in most cases)) + + if (up.NewData && !up.UseArcProps) + { + if (up.ExistOnDisk()) + { + CDirItemsStat2 &stat = stat2.NewData; + const CDirItem &di = dirItems.Items[(unsigned)up.DirIndex]; + if (di.IsDir()) + { + if (up.IsAnti) + stat.Anti_NumDirs++; + else + stat.NumDirs++; + } + #ifdef _WIN32 + else if (di.IsAltStream) + { + if (up.IsAnti) + stat.Anti_NumAltStreams++; + else + { + stat.NumAltStreams++; + stat.AltStreamsSize += di.Size; + } + } + #endif + else + { + if (up.IsAnti) + stat.Anti_NumFiles++; + else + { + stat.NumFiles++; + stat.FilesSize += di.Size; + } + } + } + } + else if (up.ArcIndex >= 0) + { + CDirItemsStat2 &stat = *(up.NewData ? &stat2.NewData : &stat2.OldData); + const CArcItem &ai = arcItems[(unsigned)up.ArcIndex]; + if (ai.IsDir) + { + if (up.IsAnti) + stat.Anti_NumDirs++; + else + stat.NumDirs++; + } + else if (ai.IsAltStream) + { + if (up.IsAnti) + stat.Anti_NumAltStreams++; + else + { + stat.NumAltStreams++; + stat.AltStreamsSize += ai.Size; + } + } + else + { + if (up.IsAnti) + stat.Anti_NumFiles++; + else + { + stat.NumFiles++; + stat.FilesSize += ai.Size; + } + } + } + } + RINOK(callback->SetNumItems(stat2)) } CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec); + updateCallbackSpec->PreserveATime = options.PreserveATime; updateCallbackSpec->ShareForWrite = options.OpenShareForWrite; + updateCallbackSpec->StopAfterOpenError = options.StopAfterOpenError; updateCallbackSpec->StdInMode = options.StdInMode; updateCallbackSpec->Callback = callback; @@ -652,6 +638,8 @@ static HRESULT Compress( updateCallbackSpec->StoreNtSecurity = options.NtSecurity.Val; updateCallbackSpec->StoreHardLinks = options.HardLinks.Val; updateCallbackSpec->StoreSymLinks = options.SymLinks.Val; + updateCallbackSpec->StoreOwnerName = options.StoreOwnerName.Val; + updateCallbackSpec->StoreOwnerId = options.StoreOwnerId.Val; updateCallbackSpec->Arc = arc; updateCallbackSpec->ArcItems = &arcItems; @@ -659,9 +647,20 @@ static HRESULT Compress( updateCallbackSpec->ProcessedItemsStatuses = processedItemsStatuses; + { + const UString arcPath = archivePath.GetFinalPath(); + updateCallbackSpec->ArcFileName = ExtractFileNameFromPath(arcPath); + } + if (options.RenamePairs.Size() != 0) updateCallbackSpec->NewNames = &newNames; + if (options.SetArcMTime) + { + // updateCallbackSpec->Need_ArcMTime_Report = true; + updateCallbackSpec->Need_LatestMTime = true; + } + CMyComPtr<IOutStream> outSeekStream; CMyComPtr<ISequentialOutStream> outStream; @@ -675,7 +674,7 @@ static HRESULT Compress( COutFileStream *outStreamSpec = NULL; CStdOutFileStream *stdOutFileStreamSpec = NULL; - COutMultiVolStream *volStreamSpec = NULL; + CMultiOutStream *volStreamSpec = NULL; if (options.VolumesSizes.Size() == 0) { @@ -698,9 +697,8 @@ static HRESULT Compress( { if (i > 0) { - FChar s[16]; - ConvertUInt32ToString(i, s); - archivePath.TempPostfix = s; + archivePath.TempPostfix.Empty(); + archivePath.TempPostfix.Add_UInt32(i); } realPath = archivePath.GetTempPath(); } @@ -729,25 +727,26 @@ static HRESULT Compress( if (arc && arc->GetGlobalOffset() > 0) return E_NOTIMPL; - volStreamSpec = new COutMultiVolStream; + volStreamSpec = new CMultiOutStream(); outSeekStream = volStreamSpec; outStream = outSeekStream; - volStreamSpec->Sizes = options.VolumesSizes; volStreamSpec->Prefix = us2fs(archivePath.GetFinalVolPath()); - volStreamSpec->Prefix += FTEXT('.'); - volStreamSpec->TempFiles = &tempFiles; - volStreamSpec->Init(); + volStreamSpec->Prefix.Add_Dot(); + volStreamSpec->Init(options.VolumesSizes); + { + CMultiOutStream_Rec &rec = multiStreams.Items.AddNew(); + rec.Spec = volStreamSpec; + rec.Ref = rec.Spec; + } /* updateCallbackSpec->VolumesSizes = volumesSizes; updateCallbackSpec->VolName = archivePath.Prefix + archivePath.Name; if (!archivePath.VolExtension.IsEmpty()) - updateCallbackSpec->VolExt = UString(L'.') + archivePath.VolExtension; + updateCallbackSpec->VolExt = UString('.') + archivePath.VolExtension; */ } - RINOK(SetProperties(outArchive, options.MethodMode.Properties)); - if (options.SfxMode) { CInFileStream *sfxStreamSpec = new CInFileStream; @@ -763,22 +762,22 @@ static HRESULT Compress( { outStreamSpec2 = new COutFileStream; sfxOutStream = outStreamSpec2; - FString realPath = us2fs(archivePath.GetFinalPath()); + const FString realPath = us2fs(archivePath.GetFinalPath()); if (!outStreamSpec2->Create(realPath, false)) return errorInfo.SetFromLastError("cannot open file", realPath); } { UInt64 sfxSize; - RINOK(sfxStreamSpec->GetSize(&sfxSize)); - RINOK(callback->WriteSfx(fs2us(options.SfxModule), sfxSize)); + RINOK(sfxStreamSpec->GetSize(&sfxSize)) + RINOK(callback->WriteSfx(fs2us(options.SfxModule), sfxSize)) } - RINOK(NCompress::CopyStream(sfxStream, sfxOutStream, NULL)); + RINOK(NCompress::CopyStream(sfxStream, sfxOutStream, NULL)) if (outStreamSpec2) { - RINOK(outStreamSpec2->Close()); + RINOK(outStreamSpec2->Close()) } } @@ -789,8 +788,8 @@ static HRESULT Compress( else { // Int64 globalOffset = arc->GetGlobalOffset(); - RINOK(arc->InStream->Seek(0, STREAM_SEEK_SET, NULL)); - RINOK(NCompress::CopyStream_ExactSize(arc->InStream, outStream, arc->ArcStreamOffset, NULL)); + RINOK(InStream_SeekToBegin(arc->InStream)) + RINOK(NCompress::CopyStream_ExactSize(arc->InStream, outStream, arc->ArcStreamOffset, NULL)) if (options.StdOutMode) tailStream = outStream; else @@ -803,10 +802,57 @@ static HRESULT Compress( } } + CFiTime ft; + FiTime_Clear(ft); + bool ft_Defined = false; + { + FOR_VECTOR (i, updatePairs2) + { + const CUpdatePair2 &pair2 = updatePairs2[i]; + CFiTime ft2; + FiTime_Clear(ft2); + bool ft2_Defined = false; + /* we use full precision of dirItem, if dirItem is defined + and (dirItem will be used or dirItem is sameTime in dir and arc */ + if (pair2.DirIndex >= 0 && + (pair2.NewProps || pair2.IsSameTime)) + { + ft2 = dirItems.Items[(unsigned)pair2.DirIndex].MTime; + ft2_Defined = true; + } + else if (pair2.UseArcProps && pair2.ArcIndex >= 0) + { + const CArcItem &arcItem = arcItems[(unsigned)pair2.ArcIndex]; + if (arcItem.MTime.Def) + { + arcItem.MTime.Write_To_FiTime(ft2); + ft2_Defined = true; + } + } + if (ft2_Defined) + { + if (!ft_Defined || Compare_FiTime(&ft, &ft2) < 0) + { + ft = ft2; + ft_Defined = true; + } + } + } + /* + if (fileTimeType != NFileTimeType::kNotDefined) + FiTime_Normalize_With_Prec(ft, fileTimeType); + */ + } + + if (volStreamSpec && options.SetArcMTime && ft_Defined) + { + volStreamSpec->MTime = ft; + volStreamSpec->MTime_Defined = true; + } HRESULT result = outArchive->UpdateItems(tailStream, updatePairs2.Size(), updateCallback); // callback->Finalize(); - RINOK(result); + RINOK(result) if (!updateCallbackSpec->AreAllFilesClosed()) { @@ -817,29 +863,43 @@ static HRESULT Compress( if (options.SetArcMTime) { - FILETIME ft; - ft.dwLowDateTime = 0; - ft.dwHighDateTime = 0; - FOR_VECTOR (i, updatePairs2) + // bool needNormalizeAfterStream; + // needParse; + /* + if (updateCallbackSpec->ArcMTime_WasReported) { - CUpdatePair2 &pair2 = updatePairs2[i]; - const FILETIME *ft2 = NULL; - if (pair2.NewProps && pair2.DirIndex >= 0) - ft2 = &dirItems.Items[pair2.DirIndex].MTime; - else if (pair2.UseArcProps && pair2.ArcIndex >= 0) - ft2 = &arcItems[pair2.ArcIndex].MTime; - if (ft2) + isDefined = updateCallbackSpec->Reported_ArcMTime.Def; + if (isDefined) + updateCallbackSpec->Reported_ArcMTime.Write_To_FiTime(ft); + else + fileTimeType = NFileTimeType::kNotDefined; + } + if (!isDefined) + */ + { + if (updateCallbackSpec->LatestMTime_Defined) { - if (::CompareFileTime(&ft, ft2) < 0) - ft = *ft2; + // CArcTime at = StreamCallback_ArcMTime; + // updateCallbackSpec->StreamCallback_ArcMTime.Write_To_FiTime(ft); + // we must normalize with precision from archive; + if (!ft_Defined || Compare_FiTime(&ft, &updateCallbackSpec->LatestMTime) < 0) + ft = updateCallbackSpec->LatestMTime; + ft_Defined = true; } + /* + if (fileTimeType != NFileTimeType::kNotDefined) + FiTime_Normalize_With_Prec(ft, fileTimeType); + */ } - if (ft.dwLowDateTime != 0 || ft.dwHighDateTime != 0) + // if (ft.dwLowDateTime != 0 || ft.dwHighDateTime != 0) + if (ft_Defined) { + // we ignore set time errors here. + // note that user could move some finished volumes to another folder. if (outStreamSpec) outStreamSpec->SetMTime(&ft); else if (volStreamSpec) - volStreamSpec->SetMTime(&ft);; + volStreamSpec->SetMTime_Final(ft); } } @@ -859,10 +919,43 @@ static HRESULT Compress( if (outStreamSpec) result = outStreamSpec->Close(); else if (volStreamSpec) - result = volStreamSpec->Close(); + { + result = volStreamSpec->FinalFlush_and_CloseFiles(st.NumVolumes); + st.IsMultiVolMode = true; + } + + RINOK(result) + + if (processedItemsStatuses) + { + FOR_VECTOR (i, updatePairs2) + { + const CUpdatePair2 &up = updatePairs2[i]; + if (up.NewData && up.DirIndex >= 0) + { + const CDirItem &di = dirItems.Items[(unsigned)up.DirIndex]; + if (di.AreReparseData() || (!di.IsDir() && di.Size == 0)) + processedItemsStatuses[(unsigned)up.DirIndex] = 1; + } + } + } + return result; } + + +static bool Censor_AreAllAllowed(const NWildcard::CCensor &censor) +{ + if (censor.Pairs.Size() != 1) + return false; + const NWildcard::CPair &pair = censor.Pairs[0]; + /* Censor_CheckPath() ignores (CPair::Prefix). + So we also ignore (CPair::Prefix) here */ + // if (!pair.Prefix.IsEmpty()) return false; + return pair.Head.AreAllAllowed(); +} + bool CensorNode_CheckPath2(const NWildcard::CCensorNode &node, const CReadArcItem &item, bool &include); static bool Censor_CheckPath(const NWildcard::CCensor &censor, const CReadArcItem &item) @@ -870,9 +963,13 @@ static bool Censor_CheckPath(const NWildcard::CCensor &censor, const CReadArcIte bool finded = false; FOR_VECTOR (i, censor.Pairs) { + /* (CPair::Prefix) in not used for matching items in archive. + So we ignore (CPair::Prefix) here */ bool include; if (CensorNode_CheckPath2(censor.Pairs[i].Head, item, include)) { + // Check it and FIXME !!!! + // here we can exclude item via some Pair, that is still allowed by another Pair if (!include) return false; finded = true; @@ -890,16 +987,18 @@ static HRESULT EnumerateInArchiveItems( arcItems.Clear(); UInt32 numItems; IInArchive *archive = arc.Archive; - RINOK(archive->GetNumberOfItems(&numItems)); + RINOK(archive->GetNumberOfItems(&numItems)) arcItems.ClearAndReserve(numItems); CReadArcItem item; + const bool allFilesAreAllowed = Censor_AreAllAllowed(censor); + for (UInt32 i = 0; i < numItems; i++) { CArcItem ai; - RINOK(arc.GetItem(i, item)); + RINOK(arc.GetItem(i, item)) ai.Name = item.Path; ai.IsDir = item.IsDir; ai.IsAltStream = @@ -913,28 +1012,14 @@ static HRESULT EnumerateInArchiveItems( if (!storeStreamsMode && ai.IsAltStream) continue; */ - ai.Censored = Censor_CheckPath(censor, item); + if (allFilesAreAllowed) + ai.Censored = true; + else + ai.Censored = Censor_CheckPath(censor, item); - RINOK(arc.GetItemMTime(i, ai.MTime, ai.MTimeDefined)); - RINOK(arc.GetItemSize(i, ai.Size, ai.SizeDefined)); - - { - CPropVariant prop; - RINOK(archive->GetProperty(i, kpidTimeType, &prop)); - if (prop.vt == VT_UI4) - { - ai.TimeType = (int)(NFileTimeType::EEnum)prop.ulVal; - switch (ai.TimeType) - { - case NFileTimeType::kWindows: - case NFileTimeType::kUnix: - case NFileTimeType::kDOS: - break; - default: - return E_FAIL; - } - } - } + // ai.MTime will be set to archive MTime, if not present in archive item + RINOK(arc.GetItem_MTime(i, ai.MTime)) + RINOK(arc.GetItem_Size(i, ai.Size, ai.Size_Defined)) ai.IndexInServer = i; arcItems.AddInReserved(ai); @@ -944,39 +1029,72 @@ static HRESULT EnumerateInArchiveItems( #if defined(_WIN32) && !defined(UNDER_CE) +#if defined(__MINGW32__) || defined(__MINGW64__) #include <mapi.h> - +#else +#include <MAPI.h> #endif -struct CRefSortPair -{ - unsigned Len; - unsigned Index; -}; +extern "C" { -#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; } +#ifdef MAPI_FORCE_UNICODE -static int CompareRefSortPair(const CRefSortPair *a1, const CRefSortPair *a2, void *) -{ - RINOZ(-MyCompare(a1->Len, a2->Len)); - return MyCompare(a1->Index, a2->Index); -} +#define Z7_WIN_LPMAPISENDMAILW LPMAPISENDMAILW +#define Z7_WIN_MapiFileDescW MapiFileDescW +#define Z7_WIN_MapiMessageW MapiMessageW +#define Z7_WIN_MapiRecipDescW MapiRecipDescW + +#else -static unsigned GetNumSlashes(const FChar *s) +typedef struct { - for (unsigned numSlashes = 0;;) - { - FChar c = *s++; - if (c == 0) - return numSlashes; - if (IS_PATH_SEPAR(c)) - numSlashes++; - } + ULONG ulReserved; + ULONG ulRecipClass; + PWSTR lpszName; + PWSTR lpszAddress; + ULONG ulEIDSize; + PVOID lpEntryID; +} Z7_WIN_MapiRecipDescW, *Z7_WIN_lpMapiRecipDescW; + +typedef struct +{ + ULONG ulReserved; + ULONG flFlags; + ULONG nPosition; + PWSTR lpszPathName; + PWSTR lpszFileName; + PVOID lpFileType; +} Z7_WIN_MapiFileDescW, *Z7_WIN_lpMapiFileDescW; + +typedef struct +{ + ULONG ulReserved; + PWSTR lpszSubject; + PWSTR lpszNoteText; + PWSTR lpszMessageType; + PWSTR lpszDateReceived; + PWSTR lpszConversationID; + FLAGS flFlags; + Z7_WIN_lpMapiRecipDescW lpOriginator; + ULONG nRecipCount; + Z7_WIN_lpMapiRecipDescW lpRecips; + ULONG nFileCount; + Z7_WIN_lpMapiFileDescW lpFiles; +} Z7_WIN_MapiMessageW, *Z7_WIN_lpMapiMessageW; + +typedef ULONG (FAR PASCAL Z7_WIN_MAPISENDMAILW)( + LHANDLE lhSession, + ULONG_PTR ulUIParam, + Z7_WIN_lpMapiMessageW lpMessage, + FLAGS flFlags, + ULONG ulReserved +); +typedef Z7_WIN_MAPISENDMAILW FAR *Z7_WIN_LPMAPISENDMAILW; + +#endif // MAPI_FORCE_UNICODE } +#endif // _WIN32 -#ifdef _WIN32 -void ConvertToLongNames(NWildcard::CCensor &censor); -#endif HRESULT UpdateArchive( CCodecs *codecs, @@ -1007,7 +1125,7 @@ HRESULT UpdateArchive( if (options.Commands.Size() != 1) return E_NOTIMPL; const CActionSet &as = options.Commands[0].ActionSet; - for (int i = 2; i < NPairState::kNumValues; i++) + for (unsigned i = 2; i < NPairState::kNumValues; i++) if (as.StateActions[i] != NPairAction::kCompress) return E_NOTIMPL; } @@ -1025,7 +1143,7 @@ HRESULT UpdateArchive( if (options.SfxMode) { CProperty property; - property.Name.SetFromAscii("rsfx"); + property.Name = "rsfx"; options.MethodMode.Properties.Add(property); if (options.SfxModule.IsEmpty()) { @@ -1036,7 +1154,7 @@ HRESULT UpdateArchive( if (options.SfxModule.Find(FCHAR_PATH_SEPARATOR) < 0) { const FString fullName = NDLL::GetModuleDirPrefix() + options.SfxModule; - if (NFind::DoesFileExist(fullName)) + if (NFind::DoesFileExist_FollowLink(fullName)) { options.SfxModule = fullName; found = true; @@ -1044,7 +1162,7 @@ HRESULT UpdateArchive( } if (!found) { - if (!NFind::DoesFileExist(options.SfxModule)) + if (!NFind::DoesFileExist_FollowLink(options.SfxModule)) return errorInfo.SetFromLastError("cannot find specified SFX module", options.SfxModule); } } @@ -1058,7 +1176,14 @@ HRESULT UpdateArchive( !options.SetArcPath(codecs, cmdArcPath2)) return E_NOTIMPL; } - const UString arcPath = options.ArchivePath.GetFinalPath(); + + UString arcPath = options.ArchivePath.GetFinalPath(); + + if (!options.VolumesSizes.IsEmpty()) + { + arcPath = options.ArchivePath.GetFinalVolPath(); + arcPath += ".001"; + } if (cmdArcPath2.IsEmpty()) { @@ -1068,10 +1193,10 @@ HRESULT UpdateArchive( else { NFind::CFileInfo fi; - if (!fi.Find(us2fs(arcPath))) + if (!fi.Find_FollowLink(us2fs(arcPath))) { if (renameMode) - throw "can't find archive";; + throw "can't find archive"; if (options.MethodMode.Type.FormatIndex < 0) { if (!options.SetArcPath(codecs, cmdArcPath2)) @@ -1081,11 +1206,39 @@ HRESULT UpdateArchive( else { if (fi.IsDir()) - throw "there is no such archive"; + return errorInfo.SetFromError_DWORD("There is a folder with the name of archive", + us2fs(arcPath), + #ifdef _WIN32 + ERROR_ACCESS_DENIED + #else + EISDIR + #endif + ); + #ifdef _WIN32 if (fi.IsDevice) return E_NOTIMPL; + #endif + + if (!options.StdOutMode && options.UpdateArchiveItself) + if (fi.IsReadOnly()) + { + return errorInfo.SetFromError_DWORD("The file is read-only", + us2fs(arcPath), + #ifdef _WIN32 + ERROR_ACCESS_DENIED + #else + EACCES + #endif + ); + } + if (options.VolumesSizes.Size() > 0) + { + errorInfo.FileNames.Add(us2fs(arcPath)); + // errorInfo.SystemError = (DWORD)E_NOTIMPL; + errorInfo.Message = kUpdateIsNotSupported_MultiVol; return E_NOTIMPL; + } CObjectVector<COpenType> types2; // change it. if (options.MethodMode.Type_Defined) @@ -1094,7 +1247,7 @@ HRESULT UpdateArchive( CIntVector excl; COpenOptions op; - #ifndef _SFX + #ifndef Z7_SFX op.props = &options.MethodMode.Properties; #endif op.codecs = codecs; @@ -1104,7 +1257,7 @@ HRESULT UpdateArchive( op.stream = NULL; op.filePath = arcPath; - RINOK(callback->StartOpenArchive(arcPath)); + RINOK(callback->StartOpenArchive(arcPath)) HRESULT result = arcLink.Open_Strict(op, openCallback); @@ -1116,23 +1269,29 @@ HRESULT UpdateArchive( if (result == S_FALSE) return E_FAIL; */ - RINOK(res2); - RINOK(result); + RINOK(res2) + RINOK(result) if (arcLink.VolumePaths.Size() > 1) { - errorInfo.SystemError = (DWORD)E_NOTIMPL; - errorInfo.Message = "Updating for multivolume archives is not implemented"; + // errorInfo.SystemError = (DWORD)E_NOTIMPL; + errorInfo.Message = kUpdateIsNotSupported_MultiVol; return E_NOTIMPL; } CArc &arc = arcLink.Arcs.Back(); - arc.MTimeDefined = !fi.IsDevice; - arc.MTime = fi.MTime; + arc.MTime.Def = + #ifdef _WIN32 + !fi.IsDevice; + #else + true; + #endif + if (arc.MTime.Def) + arc.MTime.Set_From_FiTime(fi.MTime); if (arc.ErrorInfo.ThereIsTail) { - errorInfo.SystemError = (DWORD)E_NOTIMPL; + // errorInfo.SystemError = (DWORD)E_NOTIMPL; errorInfo.Message = "There is some data block after the end of the archive"; return E_NOTIMPL; } @@ -1147,7 +1306,7 @@ HRESULT UpdateArchive( if (options.MethodMode.Type.FormatIndex < 0) { - options.MethodMode.Type.FormatIndex = codecs->FindFormatForArchiveType(kDefaultArcType); + options.MethodMode.Type.FormatIndex = codecs->FindFormatForArchiveType((UString)kDefaultArcType); if (options.MethodMode.Type.FormatIndex < 0) return E_NOTIMPL; } @@ -1172,10 +1331,11 @@ HRESULT UpdateArchive( if (options.StdInMode) { CDirItem di; + di.ClearBase(); di.Name = options.StdInFileName; di.Size = (UInt64)(Int64)-1; - di.Attrib = 0; - NTime::GetCurUtcFileTime(di.MTime); + di.SetAsFile(); + NTime::GetCurUtc_FiTime(di.MTime); di.CTime = di.ATime = di.MTime; dirItems.Items.Add(di); } @@ -1190,7 +1350,7 @@ HRESULT UpdateArchive( if (needScanning) { - RINOK(callback->StartScanning()); + RINOK(callback->StartScanning()) dirItems.SymLinks = options.SymLinks.Val; @@ -1199,10 +1359,18 @@ HRESULT UpdateArchive( #endif dirItems.ScanAltStreams = options.AltStreams.Val; + dirItems.ExcludeDirItems = censor.ExcludeDirItems; + dirItems.ExcludeFileItems = censor.ExcludeFileItems; + + dirItems.ShareForWrite = options.OpenShareForWrite; + + #ifndef _WIN32 + dirItems.StoreOwnerName = options.StoreOwnerName.Val; + #endif - HRESULT res = EnumerateItems(censor, + const HRESULT res = EnumerateItems(censor, options.PathMode, - options.AddPathPrefix, + UString(), // options.AddPathPrefix, dirItems); if (res != S_OK) @@ -1212,13 +1380,15 @@ HRESULT UpdateArchive( return res; } - RINOK(callback->FinishScanning(dirItems.Stat)); + RINOK(callback->FinishScanning(dirItems.Stat)) + // 22.00: we don't need parent folder, if absolute path mode + if (options.PathMode != NWildcard::k_AbsPath) if (censor.Pairs.Size() == 1) { NFind::CFileInfo fi; FString prefix = us2fs(censor.Pairs[0].Prefix); - prefix += FTEXT('.'); + prefix.Add_Dot(); // UString prefix = censor.Pairs[0].Prefix; /* if (prefix.Back() == WCHAR_PATH_SEPARATOR) @@ -1229,11 +1399,7 @@ HRESULT UpdateArchive( if (fi.Find(prefix)) if (fi.IsDir()) { - parentDirItem.Size = fi.Size; - parentDirItem.CTime = fi.CTime; - parentDirItem.ATime = fi.ATime; - parentDirItem.MTime = fi.MTime; - parentDirItem.Attrib = fi.Attrib; + parentDirItem.Copy_From_FileInfoBase(fi); parentDirItem_Ptr = &parentDirItem; int secureIndex = -1; @@ -1242,8 +1408,6 @@ HRESULT UpdateArchive( dirItems.AddSecurityItem(prefix, secureIndex); #endif parentDirItem.SecureIndex = secureIndex; - - parentDirItem_Ptr = &parentDirItem; } } } @@ -1286,6 +1450,31 @@ HRESULT UpdateArchive( unsigned ci; + + // self including protection + if (options.DeleteAfterCompressing) + { + for (ci = 0; ci < options.Commands.Size(); ci++) + { + CArchivePath &ap = options.Commands[ci].ArchivePath; + const FString path = us2fs(ap.GetFinalPath()); + // maybe we must compare absolute paths path here + FOR_VECTOR (i, dirItems.Items) + { + const FString phyPath = dirItems.GetPhyPath(i); + if (phyPath == path) + { + UString s; + s = "It is not allowed to include archive to itself"; + s.Add_LF(); + s += fs2us(path); + throw s; + } + } + } + } + + for (ci = 0; ci < options.Commands.Size(); ci++) { CArchivePath &ap = options.Commands[ci].ArchivePath; @@ -1315,7 +1504,7 @@ HRESULT UpdateArchive( { RINOK(EnumerateInArchiveItems( // options.StoreAltStreams, - censor, arcLink.Arcs.Back(), arcItems)); + censor, arcLink.Arcs.Back(), arcItems)) } /* @@ -1328,14 +1517,16 @@ HRESULT UpdateArchive( CByteBuffer processedItems; if (options.DeleteAfterCompressing) { - unsigned num = dirItems.Items.Size(); + const unsigned num = dirItems.Items.Size(); processedItems.Alloc(num); for (unsigned i = 0; i < num; i++) processedItems[i] = 0; } + CMultiOutStream_Bunch multiStreams; + /* - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO if (arcLink.PasswordWasAsked) { // We set password, if open have requested password @@ -1353,7 +1544,7 @@ HRESULT UpdateArchive( if (options.StdOutMode) { - name.SetFromAscii("stdout"); + name = "stdout"; isUpdating = thereIsInArchive; } else @@ -1379,18 +1570,22 @@ HRESULT UpdateArchive( parentDirItem_Ptr, tempFiles, - errorInfo, callback, st)); + multiStreams, + errorInfo, callback, st)) - RINOK(callback->FinishArchive(st)); + RINOK(callback->FinishArchive(st)) } if (thereIsInArchive) { - RINOK(arcLink.Close()); + RINOK(arcLink.Close()) arcLink.Release(); } + multiStreams.DisableDeletion(); + RINOK(multiStreams.Destruct()) + tempFiles.Paths.Clear(); if (createTempFile) { @@ -1399,9 +1594,13 @@ HRESULT UpdateArchive( CArchivePath &ap = options.Commands[0].ArchivePath; const FString &tempPath = ap.GetTempPath(); + // DWORD attrib = 0; if (thereIsInArchive) + { + // attrib = NFind::GetFileAttrib(us2fs(arcPath)); if (!DeleteFileAlways(us2fs(arcPath))) return errorInfo.SetFromLastError("cannot delete the file", us2fs(arcPath)); + } if (!MyMoveFile(tempPath, us2fs(arcPath))) { @@ -1409,6 +1608,15 @@ HRESULT UpdateArchive( errorInfo.FileNames.Add(us2fs(arcPath)); return errorInfo.Get_HRESULT_Error(); } + + /* + if (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_READONLY)) + { + DWORD attrib2 = NFind::GetFileAttrib(us2fs(arcPath)); + if (attrib2 != INVALID_FILE_ATTRIBUTES) + NDir::SetFileAttrib(us2fs(arcPath), attrib2 | FILE_ATTRIBUTE_READONLY); + } + */ } catch(...) { @@ -1428,6 +1636,19 @@ HRESULT UpdateArchive( return errorInfo.Get_HRESULT_Error(); } + FStringVector fullPaths; + unsigned i; + + for (i = 0; i < options.Commands.Size(); i++) + { + CArchivePath &ap = options.Commands[i].ArchivePath; + const FString finalPath = us2fs(ap.GetFinalPath()); + FString arcPath2; + if (!MyGetFullPathName(finalPath, arcPath2)) + return errorInfo.SetFromLastError("GetFullPathName error", finalPath); + fullPaths.Add(arcPath2); + } + /* LPMAPISENDDOCUMENTS fnSend = (LPMAPISENDDOCUMENTS)mapiLib.GetProc("MAPISendDocuments"); if (fnSend == 0) @@ -1436,69 +1657,128 @@ HRESULT UpdateArchive( return errorInfo.Get_HRESULT_Error(); } */ + const + Z7_WIN_LPMAPISENDMAILW sendMailW = Z7_GET_PROC_ADDRESS( + Z7_WIN_LPMAPISENDMAILW, mapiLib.Get_HMODULE(), + "MAPISendMailW"); + if (sendMailW) + { + + CCurrentDirRestorer curDirRestorer; + + UStringVector paths; + UStringVector names; - LPMAPISENDMAIL sendMail = (LPMAPISENDMAIL)mapiLib.GetProc("MAPISendMail"); - if (sendMail == 0) + for (i = 0; i < fullPaths.Size(); i++) { - errorInfo.SetFromLastError("7-Zip cannot find MAPISendMail function"); - return errorInfo.Get_HRESULT_Error();; + const UString arcPath2 = fs2us(fullPaths[i]); + const UString fileName = ExtractFileNameFromPath(arcPath2); + paths.Add(arcPath2); + names.Add(fileName); + // Warning!!! MAPISendDocuments function changes Current directory + // fnSend(0, ";", (LPSTR)(LPCSTR)path, (LPSTR)(LPCSTR)name, 0); } - FStringVector fullPaths; - unsigned i; + CRecordVector<Z7_WIN_MapiFileDescW> files; + files.ClearAndSetSize(paths.Size()); - for (i = 0; i < options.Commands.Size(); i++) + for (i = 0; i < paths.Size(); i++) { - CArchivePath &ap = options.Commands[i].ArchivePath; - FString finalPath = us2fs(ap.GetFinalPath()); - FString arcPath2; - if (!MyGetFullPathName(finalPath, arcPath2)) - return errorInfo.SetFromLastError("GetFullPathName error", finalPath); - fullPaths.Add(arcPath2); + Z7_WIN_MapiFileDescW &f = files[i]; + memset(&f, 0, sizeof(f)); + f.nPosition = 0xFFFFFFFF; + f.lpszPathName = paths[i].Ptr_non_const(); + f.lpszFileName = names[i].Ptr_non_const(); + } + + { + Z7_WIN_MapiMessageW m; + memset(&m, 0, sizeof(m)); + m.nFileCount = files.Size(); + m.lpFiles = &files.Front(); + + const UString addr (options.EMailAddress); + Z7_WIN_MapiRecipDescW rec; + if (!addr.IsEmpty()) + { + memset(&rec, 0, sizeof(rec)); + rec.ulRecipClass = MAPI_TO; + rec.lpszAddress = addr.Ptr_non_const(); + m.nRecipCount = 1; + m.lpRecips = &rec; + } + + sendMailW((LHANDLE)0, 0, &m, MAPI_DIALOG, 0); + } + } + else + { + const + LPMAPISENDMAIL sendMail = Z7_GET_PROC_ADDRESS( + LPMAPISENDMAIL, mapiLib.Get_HMODULE(), + "MAPISendMail"); + if (!sendMail) + { + errorInfo.SetFromLastError("7-Zip cannot find MAPISendMail function"); + return errorInfo.Get_HRESULT_Error(); } CCurrentDirRestorer curDirRestorer; + + AStringVector paths; + AStringVector names; for (i = 0; i < fullPaths.Size(); i++) { - UString arcPath2 = fs2us(fullPaths[i]); - UString fileName = ExtractFileNameFromPath(arcPath2); - AString path = GetAnsiString(arcPath2); - AString name = GetAnsiString(fileName); + const UString arcPath2 = fs2us(fullPaths[i]); + const UString fileName = ExtractFileNameFromPath(arcPath2); + paths.Add(GetAnsiString(arcPath2)); + names.Add(GetAnsiString(fileName)); + // const AString path (GetAnsiString(arcPath2)); + // const AString name (GetAnsiString(fileName)); // Warning!!! MAPISendDocuments function changes Current directory // fnSend(0, ";", (LPSTR)(LPCSTR)path, (LPSTR)(LPCSTR)name, 0); + } - MapiFileDesc f; + CRecordVector<MapiFileDesc> files; + files.ClearAndSetSize(paths.Size()); + + for (i = 0; i < paths.Size(); i++) + { + MapiFileDesc &f = files[i]; memset(&f, 0, sizeof(f)); f.nPosition = 0xFFFFFFFF; - f.lpszPathName = (char *)(const char *)path; - f.lpszFileName = (char *)(const char *)name; - + f.lpszPathName = paths[i].Ptr_non_const(); + f.lpszFileName = names[i].Ptr_non_const(); + } + + { MapiMessage m; memset(&m, 0, sizeof(m)); - m.nFileCount = 1; - m.lpFiles = &f; + m.nFileCount = files.Size(); + m.lpFiles = &files.Front(); - const AString addr = GetAnsiString(options.EMailAddress); + const AString addr (GetAnsiString(options.EMailAddress)); MapiRecipDesc rec; if (!addr.IsEmpty()) { memset(&rec, 0, sizeof(rec)); rec.ulRecipClass = MAPI_TO; - rec.lpszAddress = (char *)(const char *)addr; + rec.lpszAddress = addr.Ptr_non_const(); m.nRecipCount = 1; m.lpRecips = &rec; } sendMail((LHANDLE)0, 0, &m, MAPI_DIALOG, 0); } + } } #endif if (options.DeleteAfterCompressing) { - CRecordVector<CRefSortPair> pairs; + CRecordVector<CDirPathSortPair> pairs; FStringVector foldersNames; unsigned i; @@ -1506,47 +1786,71 @@ HRESULT UpdateArchive( for (i = 0; i < dirItems.Items.Size(); i++) { const CDirItem &dirItem = dirItems.Items[i]; - FString phyPath = dirItems.GetPhyPath(i); + const FString phyPath = dirItems.GetPhyPath(i); if (dirItem.IsDir()) { - CRefSortPair pair; + CDirPathSortPair pair; pair.Index = i; - pair.Len = GetNumSlashes(phyPath); + pair.SetNumSlashes(phyPath); pairs.Add(pair); } else { - if (processedItems[i] != 0 || dirItem.Size == 0) + // 21.04: we have set processedItems[*] before for all required items + if (processedItems[i] != 0 + // || dirItem.Size == 0 + // || dirItem.AreReparseData() + ) { - RINOK(callback->DeletingAfterArchiving(phyPath, false)); - DeleteFileAlways(phyPath); + NFind::CFileInfo fileInfo; + /* if (!SymLinks), we follow link here, similar to (dirItem) filling */ + if (fileInfo.Find(phyPath, !options.SymLinks.Val)) + { + bool is_SameSize = false; + if (options.SymLinks.Val && dirItem.AreReparseData()) + { + /* (dirItem.Size = dirItem.ReparseData.Size()) was set before. + So we don't compare sizes for that case here */ + is_SameSize = fileInfo.IsOsSymLink(); + } + else + is_SameSize = (fileInfo.Size == dirItem.Size); + + if (is_SameSize + && Compare_FiTime(&fileInfo.MTime, &dirItem.MTime) == 0 + && Compare_FiTime(&fileInfo.CTime, &dirItem.CTime) == 0) + { + RINOK(callback->DeletingAfterArchiving(phyPath, false)) + DeleteFileAlways(phyPath); + } + } } else { - // file was skipped + // file was skipped by some reason. We can throw error for debug: /* errorInfo.SystemError = 0; errorInfo.Message = "file was not processed"; - errorInfo.FileName = phyPath; + errorInfo.FileNames.Add(phyPath); return E_FAIL; */ } } } - pairs.Sort(CompareRefSortPair, NULL); + pairs.Sort2(); for (i = 0; i < pairs.Size(); i++) { - FString phyPath = dirItems.GetPhyPath(pairs[i].Index); + const FString phyPath = dirItems.GetPhyPath(pairs[i].Index); if (NFind::DoesDirExist(phyPath)) { - RINOK(callback->DeletingAfterArchiving(phyPath, true)); + RINOK(callback->DeletingAfterArchiving(phyPath, true)) RemoveDir(phyPath); } } - RINOK(callback->FinishDeletingAfterArchiving()); + RINOK(callback->FinishDeletingAfterArchiving()) } return S_OK; diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/Update.h b/3rdparty/lzma/CPP/7zip/UI/Common/Update.h index 0301ae7660e..a9459ffb614 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/Update.h +++ b/3rdparty/lzma/CPP/7zip/UI/Common/Update.h @@ -1,7 +1,7 @@ // Update.h -#ifndef __COMMON_UPDATE_H -#define __COMMON_UPDATE_H +#ifndef ZIP7_INC_COMMON_UPDATE_H +#define ZIP7_INC_COMMON_UPDATE_H #include "../../../Common/Wildcard.h" @@ -18,7 +18,7 @@ enum EArcNameMode { k_ArcNameMode_Smart, k_ArcNameMode_Exact, - k_ArcNameMode_Add, + k_ArcNameMode_Add }; struct CArchivePath @@ -34,7 +34,7 @@ struct CArchivePath FString TempPrefix; // path(folder) for temp location FString TempPostfix; - CArchivePath(): Temp(false) {}; + CArchivePath(): Temp(false) {} void ParseFromPath(const UString &path, EArcNameMode mode); UString GetPathWithoutExt() const { return Prefix + Name; } @@ -81,40 +81,46 @@ struct CRenamePair struct CUpdateOptions { - CCompressionMethodMode MethodMode; - - CObjectVector<CUpdateArchiveCommand> Commands; bool UpdateArchiveItself; - CArchivePath ArchivePath; - EArcNameMode ArcNameMode; - bool SfxMode; - FString SfxModule; - + + bool PreserveATime; bool OpenShareForWrite; + bool StopAfterOpenError; bool StdInMode; - UString StdInFileName; bool StdOutMode; - + bool EMailMode; bool EMailRemoveAfter; - UString EMailAddress; - FString WorkingDir; - NWildcard::ECensorPathMode PathMode; - UString AddPathPrefix; + bool DeleteAfterCompressing; + bool SetArcMTime; CBoolPair NtSecurity; CBoolPair AltStreams; CBoolPair HardLinks; CBoolPair SymLinks; - bool DeleteAfterCompressing; + CBoolPair StoreOwnerId; + CBoolPair StoreOwnerName; - bool SetArcMTime; + EArcNameMode ArcNameMode; + NWildcard::ECensorPathMode PathMode; + + CCompressionMethodMode MethodMode; + + CObjectVector<CUpdateArchiveCommand> Commands; + CArchivePath ArchivePath; + + FString SfxModule; + UString StdInFileName; + UString EMailAddress; + FString WorkingDir; + // UString AddPathPrefix; CObjectVector<CRenamePair> RenamePairs; + CRecordVector<UInt64> VolumesSizes; bool InitFormatIndex(const CCodecs *codecs, const CObjectVector<COpenType> &types, const UString &arcPath); bool SetArcPath(const CCodecs *codecs, const UString &arcPath); @@ -122,18 +128,24 @@ struct CUpdateOptions CUpdateOptions(): UpdateArchiveItself(true), SfxMode(false), + + PreserveATime(false), + OpenShareForWrite(false), + StopAfterOpenError(false), + StdInMode(false), StdOutMode(false), + EMailMode(false), EMailRemoveAfter(false), - OpenShareForWrite(false), - ArcNameMode(k_ArcNameMode_Smart), - PathMode(NWildcard::k_RelatPath), DeleteAfterCompressing(false), - SetArcMTime(false) + SetArcMTime(false), - {}; + ArcNameMode(k_ArcNameMode_Smart), + PathMode(NWildcard::k_RelatPath) + + {} void SetActionCommand_Add() { @@ -142,13 +154,12 @@ struct CUpdateOptions c.ActionSet = NUpdateArchive::k_ActionSet_Add; Commands.Add(c); } - - CRecordVector<UInt64> VolumesSizes; }; + struct CUpdateErrorInfo { - DWORD SystemError; + DWORD SystemError; // it's DWORD (WRes) only; AString Message; FStringVector FileNames; @@ -156,33 +167,42 @@ struct CUpdateErrorInfo HRESULT Get_HRESULT_Error() const { return SystemError == 0 ? E_FAIL : HRESULT_FROM_WIN32(SystemError); } void SetFromLastError(const char *message); HRESULT SetFromLastError(const char *message, const FString &fileName); + HRESULT SetFromError_DWORD(const char *message, const FString &fileName, DWORD error); - CUpdateErrorInfo(): SystemError(0) {}; + CUpdateErrorInfo(): SystemError(0) {} }; struct CFinishArchiveStat { UInt64 OutArcFileSize; + unsigned NumVolumes; + bool IsMultiVolMode; - CFinishArchiveStat(): OutArcFileSize(0) {} + CFinishArchiveStat(): OutArcFileSize(0), NumVolumes(0), IsMultiVolMode(false) {} }; -#define INTERFACE_IUpdateCallbackUI2(x) \ - INTERFACE_IUpdateCallbackUI(x) \ - INTERFACE_IDirItemsCallback(x) \ - virtual HRESULT OpenResult(const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result) x; \ - virtual HRESULT StartScanning() x; \ - virtual HRESULT FinishScanning(const CDirItemsStat &st) x; \ - virtual HRESULT StartOpenArchive(const wchar_t *name) x; \ - virtual HRESULT StartArchive(const wchar_t *name, bool updating) x; \ - virtual HRESULT FinishArchive(const CFinishArchiveStat &st) x; \ - virtual HRESULT DeletingAfterArchiving(const FString &path, bool isDir) x; \ - virtual HRESULT FinishDeletingAfterArchiving() x; \ - -struct IUpdateCallbackUI2: public IUpdateCallbackUI, public IDirItemsCallback +Z7_PURE_INTERFACES_BEGIN + +// INTERFACE_IUpdateCallbackUI(x) +// INTERFACE_IDirItemsCallback(x) + +#define Z7_IFACEN_IUpdateCallbackUI2(x) \ + virtual HRESULT OpenResult(const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result) x \ + virtual HRESULT StartScanning() x \ + virtual HRESULT FinishScanning(const CDirItemsStat &st) x \ + virtual HRESULT StartOpenArchive(const wchar_t *name) x \ + virtual HRESULT StartArchive(const wchar_t *name, bool updating) x \ + virtual HRESULT FinishArchive(const CFinishArchiveStat &st) x \ + virtual HRESULT DeletingAfterArchiving(const FString &path, bool isDir) x \ + virtual HRESULT FinishDeletingAfterArchiving() x \ + +DECLARE_INTERFACE(IUpdateCallbackUI2): + public IUpdateCallbackUI, + public IDirItemsCallback { - INTERFACE_IUpdateCallbackUI2(=0) + Z7_IFACE_PURE(IUpdateCallbackUI2) }; +Z7_PURE_INTERFACES_END HRESULT UpdateArchive( CCodecs *codecs, diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/UpdateAction.h b/3rdparty/lzma/CPP/7zip/UI/Common/UpdateAction.h index bc53fcdbbb1..6a3565e79a6 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/UpdateAction.h +++ b/3rdparty/lzma/CPP/7zip/UI/Common/UpdateAction.h @@ -1,7 +1,7 @@ // UpdateAction.h -#ifndef __UPDATE_ACTION_H -#define __UPDATE_ACTION_H +#ifndef ZIP7_INC_UPDATE_ACTION_H +#define ZIP7_INC_UPDATE_ACTION_H namespace NUpdateArchive { diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/UpdateCallback.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/UpdateCallback.cpp index 5499f2a1a9f..5e2860dd08d 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/UpdateCallback.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Common/UpdateCallback.cpp @@ -2,7 +2,28 @@ #include "StdAfx.h" -#ifndef _7ZIP_ST +// #include <stdio.h> + +#ifndef _WIN32 +// #include <grp.h> +// #include <pwd.h> +/* +inclusion of <sys/sysmacros.h> by <sys/types.h> is deprecated since glibc 2.25. +Since glibc 2.3.3, macros have been aliases for three GNU-specific +functions: gnu_dev_makedev(), gnu_dev_major(), and gnu_dev_minor() +*/ +// for major()/minor(): +#include <sys/types.h> +#if defined(__FreeBSD__) || defined(BSD) || defined(__APPLE__) +#else +#ifndef major +#include <sys/sysmacros.h> +#endif +#endif + +#endif // _WIN32 + +#ifndef Z7_ST #include "../../../Windows/Synchronization.h" #endif @@ -10,6 +31,7 @@ #include "../../../Common/IntToString.h" #include "../../../Common/StringConvert.h" #include "../../../Common/Wildcard.h" +#include "../../../Common/UTFConvert.h" #include "../../../Windows/FileDir.h" #include "../../../Windows/FileName.h" @@ -20,14 +42,14 @@ #include "UpdateCallback.h" #if defined(_WIN32) && !defined(UNDER_CE) -#define _USE_SECURITY_CODE +#define Z7_USE_SECURITY_CODE #include "../../../Windows/SecurityUtils.h" #endif using namespace NWindows; using namespace NFile; -#ifndef _7ZIP_ST +#ifndef Z7_ST static NSynchronization::CCriticalSection g_CriticalSection; #define MT_LOCK NSynchronization::CCriticalSectionLock lock(g_CriticalSection); #else @@ -35,12 +57,32 @@ static NSynchronization::CCriticalSection g_CriticalSection; #endif -#ifdef _USE_SECURITY_CODE +#ifdef Z7_USE_SECURITY_CODE bool InitLocalPrivileges(); #endif CArchiveUpdateCallback::CArchiveUpdateCallback(): - _hardIndex_From((UInt32)(Int32)-1), + PreserveATime(false), + ShareForWrite(false), + StopAfterOpenError(false), + StdInMode(false), + + KeepOriginalItemNames(false), + StoreNtSecurity(false), + StoreHardLinks(false), + StoreSymLinks(false), + + #ifndef _WIN32 + StoreOwnerId(false), + StoreOwnerName(false), + #endif + + /* + , Need_ArcMTime_Report(false), + , ArcMTime_WasReported(false), + */ + Need_LatestMTime(false), + LatestMTime_Defined(false), Callback(NULL), @@ -51,38 +93,33 @@ CArchiveUpdateCallback::CArchiveUpdateCallback(): ArcItems(NULL), UpdatePairs(NULL), NewNames(NULL), + Comment(NULL), + CommentIndex(-1), - ShareForWrite(false), - StdInMode(false), - - KeepOriginalItemNames(false), - StoreNtSecurity(false), - StoreHardLinks(false), - StoreSymLinks(false), - - ProcessedItemsStatuses(NULL) + ProcessedItemsStatuses(NULL), + _hardIndex_From((UInt32)(Int32)-1) { - #ifdef _USE_SECURITY_CODE + #ifdef Z7_USE_SECURITY_CODE _saclEnabled = InitLocalPrivileges(); #endif } -STDMETHODIMP CArchiveUpdateCallback::SetTotal(UInt64 size) +Z7_COM7F_IMF(CArchiveUpdateCallback::SetTotal(UInt64 size)) { COM_TRY_BEGIN return Callback->SetTotal(size); COM_TRY_END } -STDMETHODIMP CArchiveUpdateCallback::SetCompleted(const UInt64 *completeValue) +Z7_COM7F_IMF(CArchiveUpdateCallback::SetCompleted(const UInt64 *completeValue)) { COM_TRY_BEGIN return Callback->SetCompleted(completeValue); COM_TRY_END } -STDMETHODIMP CArchiveUpdateCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) +Z7_COM7F_IMF(CArchiveUpdateCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)) { COM_TRY_BEGIN return Callback->SetRatioInfo(inSize, outSize); @@ -103,17 +140,17 @@ static const CStatProp kProps[] = { NULL, kpidIsAnti, VT_BOOL} }; -STDMETHODIMP CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG **) +Z7_COM7F_IMF(CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG **) { - return CStatPropEnumerator::CreateEnumerator(kProps, ARRAY_SIZE(kProps), enumerator); + return CStatPropEnumerator::CreateEnumerator(kProps, Z7_ARRAY_SIZE(kProps), enumerator); } */ -STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 index, - Int32 *newData, Int32 *newProps, UInt32 *indexInArchive) +Z7_COM7F_IMF(CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 index, + Int32 *newData, Int32 *newProps, UInt32 *indexInArchive)) { COM_TRY_BEGIN - RINOK(Callback->CheckBreak()); + RINOK(Callback->CheckBreak()) const CUpdatePair2 &up = (*UpdatePairs)[index]; if (newData) *newData = BoolToInt(up.NewData); if (newProps) *newProps = BoolToInt(up.NewProps); @@ -121,35 +158,37 @@ STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 index, { *indexInArchive = (UInt32)(Int32)-1; if (up.ExistInArchive()) - *indexInArchive = (ArcItems == 0) ? up.ArcIndex : (*ArcItems)[up.ArcIndex].IndexInServer; + *indexInArchive = ArcItems ? (*ArcItems)[(unsigned)up.ArcIndex].IndexInServer : (UInt32)(Int32)up.ArcIndex; } return S_OK; COM_TRY_END } -STDMETHODIMP CArchiveUpdateCallback::GetRootProp(PROPID propID, PROPVARIANT *value) + +Z7_COM7F_IMF(CArchiveUpdateCallback::GetRootProp(PROPID propID, PROPVARIANT *value)) { NCOM::CPropVariant prop; switch (propID) { case kpidIsDir: prop = true; break; - case kpidAttrib: if (ParentDirItem) prop = ParentDirItem->Attrib; break; - case kpidCTime: if (ParentDirItem) prop = ParentDirItem->CTime; break; - case kpidATime: if (ParentDirItem) prop = ParentDirItem->ATime; break; - case kpidMTime: if (ParentDirItem) prop = ParentDirItem->MTime; break; + case kpidAttrib: if (ParentDirItem) prop = ParentDirItem->GetWinAttrib(); break; + case kpidCTime: if (ParentDirItem) PropVariant_SetFrom_FiTime(prop, ParentDirItem->CTime); break; + case kpidATime: if (ParentDirItem) PropVariant_SetFrom_FiTime(prop, ParentDirItem->ATime); break; + case kpidMTime: if (ParentDirItem) PropVariant_SetFrom_FiTime(prop, ParentDirItem->MTime); break; + case kpidArcFileName: if (!ArcFileName.IsEmpty()) prop = ArcFileName; break; } prop.Detach(value); return S_OK; } -STDMETHODIMP CArchiveUpdateCallback::GetParent(UInt32 /* index */, UInt32 *parent, UInt32 *parentType) +Z7_COM7F_IMF(CArchiveUpdateCallback::GetParent(UInt32 /* index */, UInt32 *parent, UInt32 *parentType)) { *parentType = NParentType::kDir; *parent = (UInt32)(Int32)-1; return S_OK; } -STDMETHODIMP CArchiveUpdateCallback::GetNumRawProps(UInt32 *numProps) +Z7_COM7F_IMF(CArchiveUpdateCallback::GetNumRawProps(UInt32 *numProps)) { *numProps = 0; if (StoreNtSecurity) @@ -157,25 +196,27 @@ STDMETHODIMP CArchiveUpdateCallback::GetNumRawProps(UInt32 *numProps) return S_OK; } -STDMETHODIMP CArchiveUpdateCallback::GetRawPropInfo(UInt32 /* index */, BSTR *name, PROPID *propID) +Z7_COM7F_IMF(CArchiveUpdateCallback::GetRawPropInfo(UInt32 /* index */, BSTR *name, PROPID *propID)) { *name = NULL; *propID = kpidNtSecure; return S_OK; } -STDMETHODIMP CArchiveUpdateCallback::GetRootRawProp(PROPID - #ifdef _USE_SECURITY_CODE +Z7_COM7F_IMF(CArchiveUpdateCallback::GetRootRawProp(PROPID propID - #endif - , const void **data, UInt32 *dataSize, UInt32 *propType) + , const void **data, UInt32 *dataSize, UInt32 *propType)) { - *data = 0; + #ifndef Z7_USE_SECURITY_CODE + UNUSED_VAR(propID) + #endif + + *data = NULL; *dataSize = 0; *propType = 0; if (!StoreNtSecurity) return S_OK; - #ifdef _USE_SECURITY_CODE + #ifdef Z7_USE_SECURITY_CODE if (propID == kpidNtSecure) { if (StdInMode) @@ -185,7 +226,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetRootRawProp(PROPID { if (ParentDirItem->SecureIndex < 0) return S_OK; - const CByteBuffer &buf = DirItems->SecureBlocks.Bufs[ParentDirItem->SecureIndex]; + const CByteBuffer &buf = DirItems->SecureBlocks.Bufs[(unsigned)ParentDirItem->SecureIndex]; *data = buf; *dataSize = (UInt32)buf.Size(); *propType = NPropDataType::kRaw; @@ -199,12 +240,10 @@ STDMETHODIMP CArchiveUpdateCallback::GetRootRawProp(PROPID return S_OK; } -// #ifdef _USE_SECURITY_CODE -// #endif -STDMETHODIMP CArchiveUpdateCallback::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) +Z7_COM7F_IMF(CArchiveUpdateCallback::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)) { - *data = 0; + *data = NULL; *dataSize = 0; *propType = 0; @@ -217,7 +256,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetRawProp(UInt32 index, PROPID propID, con const CUpdatePair2 &up = (*UpdatePairs)[index]; if (up.UseArcProps && up.ExistInArchive() && Arc->GetRawProps) return Arc->GetRawProps->GetRawProp( - ArcItems ? (*ArcItems)[up.ArcIndex].IndexInServer : up.ArcIndex, + ArcItems ? (*ArcItems)[(unsigned)up.ArcIndex].IndexInServer : (UInt32)(Int32)up.ArcIndex, propID, data, dataSize, propType); { /* @@ -227,29 +266,30 @@ STDMETHODIMP CArchiveUpdateCallback::GetRawProp(UInt32 index, PROPID propID, con if (up.IsAnti) return S_OK; - #ifndef UNDER_CE - const CDirItem &di = DirItems->Items[up.DirIndex]; + #if defined(_WIN32) && !defined(UNDER_CE) + const CDirItem &di = DirItems->Items[(unsigned)up.DirIndex]; #endif - #ifdef _USE_SECURITY_CODE + #ifdef Z7_USE_SECURITY_CODE if (propID == kpidNtSecure) { if (!StoreNtSecurity) return S_OK; if (di.SecureIndex < 0) return S_OK; - const CByteBuffer &buf = DirItems->SecureBlocks.Bufs[di.SecureIndex]; + const CByteBuffer &buf = DirItems->SecureBlocks.Bufs[(unsigned)di.SecureIndex]; *data = buf; *dataSize = (UInt32)buf.Size(); *propType = NPropDataType::kRaw; } else #endif + if (propID == kpidNtReparse) { - // propID == kpidNtReparse if (!StoreSymLinks) return S_OK; - #ifndef UNDER_CE + #if defined(_WIN32) && !defined(UNDER_CE) + // we use ReparseData2 instead of ReparseData for WIM format const CByteBuffer *buf = &di.ReparseData2; if (buf->Size() == 0) buf = &di.ReparseData; @@ -269,7 +309,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetRawProp(UInt32 index, PROPID propID, con return S_OK; } -#ifndef UNDER_CE +#if defined(_WIN32) && !defined(UNDER_CE) static UString GetRelativePath(const UString &to, const UString &from) { @@ -300,7 +340,7 @@ static UString GetRelativePath(const UString &to, const UString &from) unsigned k; for (k = i + 1; k < partsFrom.Size(); k++) - s += L".." WSTRING_PATH_SEPARATOR; + s += ".." STRING_PATH_SEPARATOR; for (k = i; k < partsTo.Size(); k++) { @@ -314,7 +354,7 @@ static UString GetRelativePath(const UString &to, const UString &from) #endif -STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +Z7_COM7F_IMF(CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) { COM_TRY_BEGIN const CUpdatePair2 &up = (*UpdatePairs)[index]; @@ -337,21 +377,25 @@ STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PR prop.Detach(value); return S_OK; } + + #if !defined(UNDER_CE) + if (up.DirIndex >= 0) { - #ifndef UNDER_CE - const CDirItem &di = DirItems->Items[up.DirIndex]; + const CDirItem &di = DirItems->Items[(unsigned)up.DirIndex]; + + #ifdef _WIN32 // if (di.IsDir()) { CReparseAttr attr; if (attr.Parse(di.ReparseData, di.ReparseData.Size())) { - UString simpleName = attr.GetPath(); - if (attr.IsRelative()) + const UString simpleName = attr.GetPath(); + if (!attr.IsSymLink_WSL() && attr.IsRelative_Win()) prop = simpleName; else { - const FString phyPath = DirItems->GetPhyPath(up.DirIndex); + const FString phyPath = DirItems->GetPhyPath((unsigned)up.DirIndex); FString fullPath; if (NDir::MyGetFullPathName(phyPath, fullPath)) { @@ -362,8 +406,26 @@ STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PR return S_OK; } } - #endif + + #else // _WIN32 + + if (di.ReparseData.Size() != 0) + { + AString utf; + utf.SetFrom_CalcLen((const char *)(const Byte *)di.ReparseData, (unsigned)di.ReparseData.Size()); + + UString us; + if (ConvertUTF8ToUnicode(utf, us)) + { + prop = us; + prop.Detach(value); + return S_OK; + } + } + + #endif // _WIN32 } + #endif // !defined(UNDER_CE) } else if (propID == kpidHardLink) { @@ -371,7 +433,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PR { const CKeyKeyValPair &pair = _map[_hardIndex_To]; const CUpdatePair2 &up2 = (*UpdatePairs)[pair.Value]; - prop = DirItems->GetLogPath(up2.DirIndex); + prop = DirItems->GetLogPath((unsigned)up2.DirIndex); prop.Detach(value); return S_OK; } @@ -395,30 +457,75 @@ STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PR } } else if (propID == kpidPath && up.NewNameIndex >= 0) - prop = (*NewNames)[up.NewNameIndex]; + prop = (*NewNames)[(unsigned)up.NewNameIndex]; + else if (propID == kpidComment + && CommentIndex >= 0 + && (unsigned)CommentIndex == index + && Comment) + prop = *Comment; else if (propID == kpidShortName && up.NewNameIndex >= 0 && up.IsMainRenameItem) { // we can generate new ShortName here; } else if ((up.UseArcProps || (KeepOriginalItemNames && (propID == kpidPath || propID == kpidIsAltStream))) && up.ExistInArchive() && Archive) - return Archive->GetProperty(ArcItems ? (*ArcItems)[up.ArcIndex].IndexInServer : up.ArcIndex, propID, value); + return Archive->GetProperty(ArcItems ? (*ArcItems)[(unsigned)up.ArcIndex].IndexInServer : (UInt32)(Int32)up.ArcIndex, propID, value); else if (up.ExistOnDisk()) { - const CDirItem &di = DirItems->Items[up.DirIndex]; + const CDirItem &di = DirItems->Items[(unsigned)up.DirIndex]; switch (propID) { - case kpidPath: prop = DirItems->GetLogPath(up.DirIndex); break; + case kpidPath: prop = DirItems->GetLogPath((unsigned)up.DirIndex); break; case kpidIsDir: prop = di.IsDir(); break; - case kpidSize: prop = di.IsDir() ? (UInt64)0 : di.Size; break; - case kpidAttrib: prop = di.Attrib; break; - case kpidCTime: prop = di.CTime; break; - case kpidATime: prop = di.ATime; break; - case kpidMTime: prop = di.MTime; break; + case kpidSize: prop = (UInt64)(di.IsDir() ? (UInt64)0 : di.Size); break; + case kpidCTime: PropVariant_SetFrom_FiTime(prop, di.CTime); break; + case kpidATime: PropVariant_SetFrom_FiTime(prop, di.ATime); break; + case kpidMTime: PropVariant_SetFrom_FiTime(prop, di.MTime); break; + case kpidAttrib: prop = (UInt32)di.GetWinAttrib(); break; + case kpidPosixAttrib: prop = (UInt32)di.GetPosixAttrib(); break; + + #if defined(_WIN32) case kpidIsAltStream: prop = di.IsAltStream; break; - #if defined(_WIN32) && !defined(UNDER_CE) // case kpidShortName: prop = di.ShortName; break; - #endif + #else + + #if defined(__APPLE__) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wsign-conversion" + #endif + + case kpidDeviceMajor: + /* + printf("\ndi.mode = %o\n", di.mode); + printf("\nst.st_rdev major = %d\n", (unsigned)major(di.rdev)); + printf("\nst.st_rdev minor = %d\n", (unsigned)minor(di.rdev)); + */ + if (S_ISCHR(di.mode) || S_ISBLK(di.mode)) + prop = (UInt32)major(di.rdev); + break; + + case kpidDeviceMinor: + if (S_ISCHR(di.mode) || S_ISBLK(di.mode)) + prop = (UInt32)minor(di.rdev); + break; + + #if defined(__APPLE__) + #pragma GCC diagnostic pop + #endif + + // case kpidDevice: if (S_ISCHR(di.mode) || S_ISBLK(di.mode)) prop = (UInt64)(di.rdev); break; + + case kpidUserId: if (StoreOwnerId) prop = (UInt32)di.uid; break; + case kpidGroupId: if (StoreOwnerId) prop = (UInt32)di.gid; break; + case kpidUser: + if (di.OwnerNameIndex >= 0) + prop = DirItems->OwnerNameMap.Strings[(unsigned)di.OwnerNameIndex]; + break; + case kpidGroup: + if (di.OwnerGroupIndex >= 0) + prop = DirItems->OwnerGroupMap.Strings[(unsigned)di.OwnerGroupIndex]; + break; + #endif } } prop.Detach(value); @@ -426,11 +533,22 @@ STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PR COM_TRY_END } -#ifndef _7ZIP_ST -static NSynchronization::CCriticalSection CS; +#ifndef Z7_ST +static NSynchronization::CCriticalSection g_CS; #endif -STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStream **inStream, UInt32 mode) +void CArchiveUpdateCallback::UpdateProcessedItemStatus(unsigned dirIndex) +{ + if (ProcessedItemsStatuses) + { + #ifndef Z7_ST + NSynchronization::CCriticalSectionLock lock(g_CS); + #endif + ProcessedItemsStatuses[dirIndex] = 1; + } +} + +Z7_COM7F_IMF(CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStream **inStream, UInt32 mode)) { COM_TRY_BEGIN *inStream = NULL; @@ -438,7 +556,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStrea if (!up.NewData) return E_FAIL; - RINOK(Callback->CheckBreak()); + RINOK(Callback->CheckBreak()) // RINOK(Callback->Finalize()); bool isDir = IsDir(up); @@ -447,10 +565,10 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStrea { UString name; if (up.ArcIndex >= 0) - name = (*ArcItems)[up.ArcIndex].Name; + name = (*ArcItems)[(unsigned)up.ArcIndex].Name; else if (up.DirIndex >= 0) - name = DirItems->GetLogPath(up.DirIndex); - RINOK(Callback->GetStream(name, isDir, true, mode)); + name = DirItems->GetLogPath((unsigned)up.DirIndex); + RINOK(Callback->GetStream(name, isDir, true, mode)) /* 9.33: fixed. Handlers expect real stream object for files, even for anti-file. so we return empty stream */ @@ -465,7 +583,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStrea return S_OK; } - RINOK(Callback->GetStream(DirItems->GetLogPath(up.DirIndex), isDir, false, mode)); + RINOK(Callback->GetStream(DirItems->GetLogPath((unsigned)up.DirIndex), isDir, false, mode)) if (isDir) return S_OK; @@ -482,32 +600,121 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStrea } else { + #if !defined(UNDER_CE) + const CDirItem &di = DirItems->Items[(unsigned)up.DirIndex]; + if (di.AreReparseData()) + { + /* + // we still need DeviceIoControlOut() instead of Read + if (!inStreamSpec->File.OpenReparse(path)) + { + return Callback->OpenFileError(path, ::GetLastError()); + } + */ + // 20.03: we use Reparse Data instead of real data + + CBufInStream *inStreamSpec = new CBufInStream(); + CMyComPtr<ISequentialInStream> inStreamLoc = inStreamSpec; + inStreamSpec->Init(di.ReparseData, di.ReparseData.Size()); + *inStream = inStreamLoc.Detach(); + + UpdateProcessedItemStatus((unsigned)up.DirIndex); + return S_OK; + } + #endif // !defined(UNDER_CE) + CInFileStream *inStreamSpec = new CInFileStream; CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec); + /* + // for debug: + #ifdef _WIN32 + inStreamSpec->StoreOwnerName = true; + inStreamSpec->OwnerName = "user_name"; + inStreamSpec->OwnerName += di.Name; + inStreamSpec->OwnerName += "11111111112222222222222333333333333"; + inStreamSpec->OwnerGroup = "gname_"; + inStreamSpec->OwnerGroup += inStreamSpec->OwnerName; + #endif + */ + + #ifndef _WIN32 + inStreamSpec->StoreOwnerId = StoreOwnerId; + inStreamSpec->StoreOwnerName = StoreOwnerName; + + // if (StoreOwner) + { + inStreamSpec->_uid = di.uid; + inStreamSpec->_gid = di.gid; + if (di.OwnerNameIndex >= 0) + inStreamSpec->OwnerName = DirItems->OwnerNameMap.Strings[(unsigned)di.OwnerNameIndex]; + if (di.OwnerGroupIndex >= 0) + inStreamSpec->OwnerGroup = DirItems->OwnerGroupMap.Strings[(unsigned)di.OwnerGroupIndex]; + } + #endif + inStreamSpec->SupportHardLinks = StoreHardLinks; - inStreamSpec->Callback = this; - inStreamSpec->CallbackRef = index; + const bool preserveATime = (PreserveATime + || mode == NUpdateNotifyOp::kAnalyze); // 22.00 : we don't change access time in Analyze pass. + inStreamSpec->Set_PreserveATime(preserveATime); - const FString path = DirItems->GetPhyPath(up.DirIndex); + const FString path = DirItems->GetPhyPath((unsigned)up.DirIndex); _openFiles_Indexes.Add(index); _openFiles_Paths.Add(path); + // _openFiles_Streams.Add(inStreamSpec); - #if defined(_WIN32) && !defined(UNDER_CE) - if (DirItems->Items[up.DirIndex].AreReparseData()) + /* 21.02 : we set Callback/CallbackRef after _openFiles_Indexes adding + for correct working if exception was raised in GetPhyPath */ + inStreamSpec->Callback = this; + inStreamSpec->CallbackRef = index; + + if (!inStreamSpec->OpenShared(path, ShareForWrite)) { - if (!inStreamSpec->File.OpenReparse(path)) + bool isOpen = false; + if (preserveATime) { - return Callback->OpenFileError(path, ::GetLastError()); + inStreamSpec->Set_PreserveATime(false); + isOpen = inStreamSpec->OpenShared(path, ShareForWrite); + } + if (!isOpen) + { + const DWORD error = ::GetLastError(); + const HRESULT hres = Callback->OpenFileError(path, error); + if (hres == S_OK || hres == S_FALSE) + if (StopAfterOpenError || + // v23: we check also for some critical errors: + #ifdef _WIN32 + error == ERROR_NO_SYSTEM_RESOURCES + #else + error == EMFILE + #endif + ) + { + if (error == 0) + return E_FAIL; + return HRESULT_FROM_WIN32(error); + } + return hres; } } - else - #endif - if (!inStreamSpec->OpenShared(path, ShareForWrite)) + + /* + { + // for debug: + Byte b = 0; + UInt32 processedSize = 0; + if (inStreamSpec->Read(&b, 1, &processedSize) != S_OK || + processedSize != 1) + return E_FAIL; + } + */ + + if (Need_LatestMTime) { - return Callback->OpenFileError(path, ::GetLastError()); + inStreamSpec->ReloadProps(); } + // #if defined(Z7_FILE_STREAMS_USE_WIN_FILE) || !defined(_WIN32) if (StoreHardLinks) { CStreamFileProps props; @@ -519,8 +726,8 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStrea pair.Key1 = props.VolID; pair.Key2 = props.FileID_Low; pair.Value = index; - unsigned numItems = _map.Size(); - unsigned pairIndex = _map.AddToUniqueSorted2(pair); + const unsigned numItems = _map.Size(); + const unsigned pairIndex = _map.AddToUniqueSorted2(pair); if (numItems == _map.Size()) { // const CKeyKeyValPair &pair2 = _map.Pairs[pairIndex]; @@ -532,14 +739,9 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStrea } } } + // #endif - if (ProcessedItemsStatuses) - { - #ifndef _7ZIP_ST - NSynchronization::CCriticalSectionLock lock(CS); - #endif - ProcessedItemsStatuses[(unsigned)up.DirIndex] = 1; - } + UpdateProcessedItemStatus((unsigned)up.DirIndex); *inStream = inStreamLoc.Detach(); } @@ -547,14 +749,14 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStrea COM_TRY_END } -STDMETHODIMP CArchiveUpdateCallback::SetOperationResult(Int32 opRes) +Z7_COM7F_IMF(CArchiveUpdateCallback::SetOperationResult(Int32 opRes)) { COM_TRY_BEGIN return Callback->SetOperationResult(opRes); COM_TRY_END } -STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream) +Z7_COM7F_IMF(CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream)) { COM_TRY_BEGIN return GetStream2(index, inStream, @@ -564,10 +766,12 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream COM_TRY_END } -STDMETHODIMP CArchiveUpdateCallback::ReportOperation(UInt32 indexType, UInt32 index, UInt32 op) +Z7_COM7F_IMF(CArchiveUpdateCallback::ReportOperation(UInt32 indexType, UInt32 index, UInt32 op)) { COM_TRY_BEGIN + // if (op == NUpdateNotifyOp::kOpFinished) return Callback->ReportFinished(indexType, index); + bool isDir = false; if (indexType == NArchive::NEventIndexType::kOutArcIndex) @@ -578,11 +782,11 @@ STDMETHODIMP CArchiveUpdateCallback::ReportOperation(UInt32 indexType, UInt32 in const CUpdatePair2 &up = (*UpdatePairs)[index]; if (up.ExistOnDisk()) { - name = DirItems->GetLogPath(up.DirIndex); - isDir = DirItems->Items[up.DirIndex].IsDir(); + name = DirItems->GetLogPath((unsigned)up.DirIndex); + isDir = DirItems->Items[(unsigned)up.DirIndex].IsDir(); } } - return Callback->ReportUpdateOpeartion(op, name.IsEmpty() ? NULL : name.Ptr(), isDir); + return Callback->ReportUpdateOperation(op, name.IsEmpty() ? NULL : name.Ptr(), isDir); } wchar_t temp[16]; @@ -601,9 +805,9 @@ STDMETHODIMP CArchiveUpdateCallback::ReportOperation(UInt32 indexType, UInt32 in } else if (Arc) { - RINOK(Arc->GetItemPath(index, s2)); + RINOK(Arc->GetItem_Path(index, s2)) s = s2; - RINOK(Archive_IsItem_Dir(Arc->Archive, index, isDir)); + RINOK(Archive_IsItem_Dir(Arc->Archive, index, isDir)) } } } @@ -617,12 +821,12 @@ STDMETHODIMP CArchiveUpdateCallback::ReportOperation(UInt32 indexType, UInt32 in if (!s) s = L""; - return Callback->ReportUpdateOpeartion(op, s, isDir); + return Callback->ReportUpdateOperation(op, s, isDir); COM_TRY_END } -STDMETHODIMP CArchiveUpdateCallback::ReportExtractResult(UInt32 indexType, UInt32 index, Int32 opRes) +Z7_COM7F_IMF(CArchiveUpdateCallback::ReportExtractResult(UInt32 indexType, UInt32 index, Int32 opRes)) { COM_TRY_BEGIN @@ -656,12 +860,12 @@ STDMETHODIMP CArchiveUpdateCallback::ReportExtractResult(UInt32 indexType, UInt3 s = (*ArcItems)[index].Name; else if (Arc) { - RINOK(Arc->GetItemPath(index, s2)); + RINOK(Arc->GetItem_Path(index, s2)) s = s2; } if (Archive) { - RINOK(Archive_GetItemBoolProp(Archive, index, kpidEncrypted, isEncrypted)); + RINOK(Archive_GetItemBoolProp(Archive, index, kpidEncrypted, isEncrypted)) } } } @@ -677,7 +881,52 @@ STDMETHODIMP CArchiveUpdateCallback::ReportExtractResult(UInt32 indexType, UInt3 COM_TRY_END } -STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size) + +/* +Z7_COM7F_IMF(CArchiveUpdateCallback::DoNeedArcProp(PROPID propID, Int32 *answer)) +{ + *answer = 0; + if (Need_ArcMTime_Report && propID == kpidComboMTime) + *answer = 1; + return S_OK; +} + +Z7_COM7F_IMF(CArchiveUpdateCallback::ReportProp(UInt32 indexType, UInt32 index, PROPID propID, const PROPVARIANT *value)) +{ + if (indexType == NArchive::NEventIndexType::kArcProp) + { + if (propID == kpidComboMTime) + { + ArcMTime_WasReported = true; + if (value->vt == VT_FILETIME) + { + Reported_ArcMTime.Set_From_Prop(*value); + Reported_ArcMTime.Def = true; + } + else + { + Reported_ArcMTime.Clear(); + if (value->vt != VT_EMPTY) + return E_FAIL; // for debug + } + } + } + return Callback->ReportProp(indexType, index, propID, value); +} + +Z7_COM7F_IMF(CArchiveUpdateCallback::ReportRawProp(UInt32 indexType, UInt32 index, + PROPID propID, const void *data, UInt32 dataSize, UInt32 propType)) +{ + return Callback->ReportRawProp(indexType, index, propID, data, dataSize, propType); +} + +Z7_COM7F_IMF(CArchiveUpdateCallback::ReportFinished(UInt32 indexType, UInt32 index, Int32 opRes)) +{ + return Callback->ReportFinished(indexType, index, opRes); +} +*/ + +Z7_COM7F_IMF(CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size)) { if (VolumesSizes.Size() == 0) return S_FALSE; @@ -687,35 +936,35 @@ STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size) return S_OK; } -STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream) +Z7_COM7F_IMF(CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream)) { COM_TRY_BEGIN - FChar temp[16]; + char temp[16]; ConvertUInt32ToString(index + 1, temp); - FString res = temp; + FString res (temp); while (res.Len() < 2) res.InsertAtFront(FTEXT('0')); FString fileName = VolName; - fileName += FTEXT('.'); + fileName.Add_Dot(); fileName += res; fileName += VolExt; COutFileStream *streamSpec = new COutFileStream; CMyComPtr<ISequentialOutStream> streamLoc(streamSpec); if (!streamSpec->Create(fileName, false)) - return ::GetLastError(); + return GetLastError_noZero_HRESULT(); *volumeStream = streamLoc.Detach(); return S_OK; COM_TRY_END } -STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) +Z7_COM7F_IMF(CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)) { COM_TRY_BEGIN return Callback->CryptoGetTextPassword2(passwordIsDefined, password); COM_TRY_END } -STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword(BSTR *password) +Z7_COM7F_IMF(CArchiveUpdateCallback::CryptoGetTextPassword(BSTR *password)) { COM_TRY_BEGIN return Callback->CryptoGetTextPassword(password); @@ -724,15 +973,18 @@ STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword(BSTR *password) HRESULT CArchiveUpdateCallback::InFileStream_On_Error(UINT_PTR val, DWORD error) { - if (error == ERROR_LOCK_VIOLATION) + #ifdef _WIN32 // FIX IT !!! + // why did we check only for ERROR_LOCK_VIOLATION ? + // if (error == ERROR_LOCK_VIOLATION) + #endif { MT_LOCK - UInt32 index = (UInt32)val; + const UInt32 index = (UInt32)val; FOR_VECTOR(i, _openFiles_Indexes) { if (_openFiles_Indexes[i] == index) { - RINOK(Callback->ReadingFileError(_openFiles_Paths[i], error)); + RINOK(Callback->ReadingFileError(_openFiles_Paths[i], error)) break; } } @@ -740,18 +992,35 @@ HRESULT CArchiveUpdateCallback::InFileStream_On_Error(UINT_PTR val, DWORD error) return HRESULT_FROM_WIN32(error); } -void CArchiveUpdateCallback::InFileStream_On_Destroy(UINT_PTR val) +void CArchiveUpdateCallback::InFileStream_On_Destroy(CInFileStream *stream, UINT_PTR val) { MT_LOCK - UInt32 index = (UInt32)val; + if (Need_LatestMTime) + { + if (stream->_info_WasLoaded) + { + const CFiTime &ft = ST_MTIME(stream->_info); + if (!LatestMTime_Defined + || Compare_FiTime(&LatestMTime, &ft) < 0) + LatestMTime = ft; + LatestMTime_Defined = true; + } + } + const UInt32 index = (UInt32)val; FOR_VECTOR(i, _openFiles_Indexes) { if (_openFiles_Indexes[i] == index) { _openFiles_Indexes.Delete(i); _openFiles_Paths.Delete(i); + // _openFiles_Streams.Delete(i); return; } } - throw 20141125; + /* 21.02 : this function can be called in destructor. + And destructor can be called after some exception. + If we don't want to throw exception in desctructors or after another exceptions, + we must disable the code below that raises new exception. + */ + // throw 20141125; } diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/UpdateCallback.h b/3rdparty/lzma/CPP/7zip/UI/Common/UpdateCallback.h index 4ff4a7ebe1d..379b8146293 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/UpdateCallback.h +++ b/3rdparty/lzma/CPP/7zip/UI/Common/UpdateCallback.h @@ -1,7 +1,7 @@ // UpdateCallback.h -#ifndef __UPDATE_CALLBACK_H -#define __UPDATE_CALLBACK_H +#ifndef ZIP7_INC_UPDATE_CALLBACK_H +#define ZIP7_INC_UPDATE_CALLBACK_H #include "../../../Common/MyCom.h" @@ -15,31 +15,51 @@ #include "OpenArchive.h" -#define INTERFACE_IUpdateCallbackUI(x) \ - virtual HRESULT WriteSfx(const wchar_t *name, UInt64 size) x; \ - virtual HRESULT SetTotal(UInt64 size) x; \ - virtual HRESULT SetCompleted(const UInt64 *completeValue) x; \ - virtual HRESULT SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) x; \ - virtual HRESULT CheckBreak() x; \ - /* virtual HRESULT Finalize() x; */ \ - virtual HRESULT SetNumItems(UInt64 numItems) x; \ - virtual HRESULT GetStream(const wchar_t *name, bool isDir, bool isAnti, UInt32 mode) x; \ - virtual HRESULT OpenFileError(const FString &path, DWORD systemError) x; \ - virtual HRESULT ReadingFileError(const FString &path, DWORD systemError) x; \ - virtual HRESULT SetOperationResult(Int32 opRes) x; \ - virtual HRESULT ReportExtractResult(Int32 opRes, Int32 isEncrypted, const wchar_t *name) x; \ - virtual HRESULT ReportUpdateOpeartion(UInt32 op, const wchar_t *name, bool isDir) x; \ - /* virtual HRESULT SetPassword(const UString &password) x; */ \ - virtual HRESULT CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) x; \ - virtual HRESULT CryptoGetTextPassword(BSTR *password) x; \ - virtual HRESULT ShowDeleteFile(const wchar_t *name, bool isDir) x; \ - /* virtual HRESULT CloseProgress() { return S_OK; } */ - -struct IUpdateCallbackUI +struct CArcToDoStat { - INTERFACE_IUpdateCallbackUI(=0) + CDirItemsStat2 NewData; + CDirItemsStat2 OldData; + CDirItemsStat2 DeleteData; + + UInt64 Get_NumDataItems_Total() const + { + return NewData.Get_NumDataItems2() + OldData.Get_NumDataItems2(); + } }; + +Z7_PURE_INTERFACES_BEGIN + +#define Z7_IFACEN_IUpdateCallbackUI(x) \ + virtual HRESULT WriteSfx(const wchar_t *name, UInt64 size) x \ + virtual HRESULT SetTotal(UInt64 size) x \ + virtual HRESULT SetCompleted(const UInt64 *completeValue) x \ + virtual HRESULT SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) x \ + virtual HRESULT CheckBreak() x \ + /* virtual HRESULT Finalize() x */ \ + virtual HRESULT SetNumItems(const CArcToDoStat &stat) x \ + virtual HRESULT GetStream(const wchar_t *name, bool isDir, bool isAnti, UInt32 mode) x \ + virtual HRESULT OpenFileError(const FString &path, DWORD systemError) x \ + virtual HRESULT ReadingFileError(const FString &path, DWORD systemError) x \ + virtual HRESULT SetOperationResult(Int32 opRes) x \ + virtual HRESULT ReportExtractResult(Int32 opRes, Int32 isEncrypted, const wchar_t *name) x \ + virtual HRESULT ReportUpdateOperation(UInt32 op, const wchar_t *name, bool isDir) x \ + /* virtual HRESULT SetPassword(const UString &password) x */ \ + virtual HRESULT CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) x \ + virtual HRESULT CryptoGetTextPassword(BSTR *password) x \ + virtual HRESULT ShowDeleteFile(const wchar_t *name, bool isDir) x \ + + /* + virtual HRESULT ReportProp(UInt32 indexType, UInt32 index, PROPID propID, const PROPVARIANT *value) x \ + virtual HRESULT ReportRawProp(UInt32 indexType, UInt32 index, PROPID propID, const void *data, UInt32 dataSize, UInt32 propType) x \ + virtual HRESULT ReportFinished(UInt32 indexType, UInt32 index, Int32 opRes) x \ + */ + + /* virtual HRESULT CloseProgress() { return S_OK; } */ + +Z7_IFACE_DECL_PURE(IUpdateCallbackUI) +Z7_PURE_INTERFACES_END + struct CKeyKeyValPair { UInt64 Key1; @@ -55,10 +75,11 @@ struct CKeyKeyValPair }; -class CArchiveUpdateCallback: +class CArchiveUpdateCallback Z7_final: public IArchiveUpdateCallback2, public IArchiveUpdateCallbackFile, - public IArchiveExtractCallbackMessage, + // public IArchiveUpdateCallbackArcProp, + public IArchiveExtractCallbackMessage2, public IArchiveGetRawProps, public IArchiveGetRootProps, public ICryptoGetTextPassword2, @@ -67,48 +88,63 @@ class CArchiveUpdateCallback: public IInFileStream_Callback, public CMyUnknownImp { - #if defined(_WIN32) && !defined(UNDER_CE) - bool _saclEnabled; - #endif - CRecordVector<CKeyKeyValPair> _map; - - UInt32 _hardIndex_From; - UInt32 _hardIndex_To; + Z7_COM_QI_BEGIN2(IArchiveUpdateCallback2) + Z7_COM_QI_ENTRY(IArchiveUpdateCallbackFile) + // Z7_COM_QI_ENTRY(IArchiveUpdateCallbackArcProp) + Z7_COM_QI_ENTRY(IArchiveExtractCallbackMessage2) + Z7_COM_QI_ENTRY(IArchiveGetRawProps) + Z7_COM_QI_ENTRY(IArchiveGetRootProps) + Z7_COM_QI_ENTRY(ICryptoGetTextPassword2) + Z7_COM_QI_ENTRY(ICryptoGetTextPassword) + Z7_COM_QI_ENTRY(ICompressProgressInfo) + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(ICompressProgressInfo) + + Z7_IFACE_COM7_IMP(IProgress) + Z7_IFACE_COM7_IMP(IArchiveUpdateCallback) + Z7_IFACE_COM7_IMP(IArchiveUpdateCallback2) + Z7_IFACE_COM7_IMP(IArchiveUpdateCallbackFile) + // Z7_IFACE_COM7_IMP(IArchiveUpdateCallbackArcProp) + Z7_IFACE_COM7_IMP(IArchiveExtractCallbackMessage2) + Z7_IFACE_COM7_IMP(IArchiveGetRawProps) + Z7_IFACE_COM7_IMP(IArchiveGetRootProps) + Z7_IFACE_COM7_IMP(ICryptoGetTextPassword2) + Z7_IFACE_COM7_IMP(ICryptoGetTextPassword) + + + void UpdateProcessedItemStatus(unsigned dirIndex); public: - MY_QUERYINTERFACE_BEGIN2(IArchiveUpdateCallback2) - MY_QUERYINTERFACE_ENTRY(IArchiveUpdateCallbackFile) - MY_QUERYINTERFACE_ENTRY(IArchiveExtractCallbackMessage) - MY_QUERYINTERFACE_ENTRY(IArchiveGetRawProps) - MY_QUERYINTERFACE_ENTRY(IArchiveGetRootProps) - MY_QUERYINTERFACE_ENTRY(ICryptoGetTextPassword2) - MY_QUERYINTERFACE_ENTRY(ICryptoGetTextPassword) - MY_QUERYINTERFACE_ENTRY(ICompressProgressInfo) - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE + bool PreserveATime; + bool ShareForWrite; + bool StopAfterOpenError; + bool StdInMode; + bool KeepOriginalItemNames; + bool StoreNtSecurity; + bool StoreHardLinks; + bool StoreSymLinks; - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); + bool StoreOwnerId; + bool StoreOwnerName; - INTERFACE_IArchiveUpdateCallback2(;) - INTERFACE_IArchiveUpdateCallbackFile(;) - INTERFACE_IArchiveExtractCallbackMessage(;) - INTERFACE_IArchiveGetRawProps(;) - INTERFACE_IArchiveGetRootProps(;) + bool Need_LatestMTime; + bool LatestMTime_Defined; - STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password); - STDMETHOD(CryptoGetTextPassword)(BSTR *password); + /* + bool Need_ArcMTime_Report; + bool ArcMTime_WasReported; + */ CRecordVector<UInt32> _openFiles_Indexes; FStringVector _openFiles_Paths; + // CRecordVector< CInFileStream* > _openFiles_Streams; bool AreAllFilesClosed() const { return _openFiles_Indexes.IsEmpty(); } - virtual HRESULT InFileStream_On_Error(UINT_PTR val, DWORD error); - virtual void InFileStream_On_Destroy(UINT_PTR val); - - CRecordVector<UInt64> VolumesSizes; - FString VolName; - FString VolExt; + virtual HRESULT InFileStream_On_Error(UINT_PTR val, DWORD error) Z7_override; + virtual void InFileStream_On_Destroy(CInFileStream *stream, UINT_PTR val) Z7_override; IUpdateCallbackUI *Callback; @@ -119,15 +155,20 @@ public: CMyComPtr<IInArchive> Archive; const CObjectVector<CArcItem> *ArcItems; const CRecordVector<CUpdatePair2> *UpdatePairs; - const UStringVector *NewNames; - bool ShareForWrite; - bool StdInMode; + CRecordVector<UInt64> VolumesSizes; + FString VolName; + FString VolExt; + UString ArcFileName; // without path prefix - bool KeepOriginalItemNames; - bool StoreNtSecurity; - bool StoreHardLinks; - bool StoreSymLinks; + const UStringVector *NewNames; + const UString *Comment; + int CommentIndex; + + /* + CArcTime Reported_ArcMTime; + */ + CFiTime LatestMTime; Byte *ProcessedItemsStatuses; @@ -137,11 +178,20 @@ public: bool IsDir(const CUpdatePair2 &up) const { if (up.DirIndex >= 0) - return DirItems->Items[up.DirIndex].IsDir(); + return DirItems->Items[(unsigned)up.DirIndex].IsDir(); else if (up.ArcIndex >= 0) - return (*ArcItems)[up.ArcIndex].IsDir; + return (*ArcItems)[(unsigned)up.ArcIndex].IsDir; return false; } + +private: + #if defined(_WIN32) && !defined(UNDER_CE) + bool _saclEnabled; + #endif + CRecordVector<CKeyKeyValPair> _map; + + UInt32 _hardIndex_From; + UInt32 _hardIndex_To; }; #endif diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/UpdatePair.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/UpdatePair.cpp index e21151974be..99b0aafb281 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/UpdatePair.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Common/UpdatePair.cpp @@ -3,6 +3,7 @@ #include "StdAfx.h" #include <time.h> +// #include <stdio.h> #include "../../../Common/Wildcard.h" @@ -14,38 +15,99 @@ using namespace NWindows; using namespace NTime; -static int MyCompareTime(NFileTimeType::EEnum fileTimeType, const FILETIME &time1, const FILETIME &time2) + +/* + a2.Prec = + { + 0 (k_PropVar_TimePrec_0): + if GetProperty(kpidMTime) returned 0 and + GetProperty(kpidTimeType) did not returned VT_UI4. + 7z, wim, tar in 7-Zip before v21) + in that case we use + (prec) that is set by IOutArchive::GetFileTimeType() + } +*/ + +static int MyCompareTime(unsigned prec, const CFiTime &f1, const CArcTime &a2) { - switch (fileTimeType) + // except of precision, we also have limitation, when timestamp is out of range + + /* if (Prec) in archive item is defined, then use global (prec) */ + if (a2.Prec != k_PropVar_TimePrec_0) + prec = a2.Prec; + + CArcTime a1; + a1.Set_From_FiTime(f1); + /* Set_From_FiTime() must set full form precision: + k_PropVar_TimePrec_Base + numDigits + windows: 7 digits, non-windows: 9 digits */ + + if (prec == k_PropVar_TimePrec_DOS) { - case NFileTimeType::kWindows: - return ::CompareFileTime(&time1, &time2); - case NFileTimeType::kUnix: - { - UInt32 unixTime1, unixTime2; - FileTimeToUnixTime(time1, unixTime1); - FileTimeToUnixTime(time2, unixTime2); - return MyCompare(unixTime1, unixTime2); - } - case NFileTimeType::kDOS: - { - UInt32 dosTime1, dosTime2; - FileTimeToDosTime(time1, dosTime1); - FileTimeToDosTime(time2, dosTime2); - return MyCompare(dosTime1, dosTime2); - } + const UInt32 dosTime1 = a1.Get_DosTime(); + const UInt32 dosTime2 = a2.Get_DosTime(); + return MyCompare(dosTime1, dosTime2); } - throw 4191618; + + if (prec == k_PropVar_TimePrec_Unix) + { + const Int64 u2 = FileTime_To_UnixTime64(a2.FT); + if (u2 == 0 || u2 == (UInt32)0xFFFFFFFF) + { + // timestamp probably was saturated in archive to 32-bit + // so we use saturated 32-bit value for disk file too. + UInt32 u1; + FileTime_To_UnixTime(a1.FT, u1); + const UInt32 u2_32 = (UInt32)u2; + return MyCompare(u1, u2_32); + } + + const Int64 u1 = FileTime_To_UnixTime64(a1.FT); + return MyCompare(u1, u2); + // prec = k_PropVar_TimePrec_Base; // for debug + } + + if (prec == k_PropVar_TimePrec_0) + prec = k_PropVar_TimePrec_Base + 7; + else if (prec == k_PropVar_TimePrec_HighPrec) + prec = k_PropVar_TimePrec_Base + 9; + else if (prec < k_PropVar_TimePrec_Base) + prec = k_PropVar_TimePrec_Base; + else if (prec > k_PropVar_TimePrec_Base + 9) + prec = k_PropVar_TimePrec_Base + 7; + + // prec now is full form: k_PropVar_TimePrec_Base + numDigits; + if (prec > a1.Prec && a1.Prec >= k_PropVar_TimePrec_Base) + prec = a1.Prec; + + const unsigned numDigits = prec - k_PropVar_TimePrec_Base; + if (numDigits >= 7) + { + const int comp = CompareFileTime(&a1.FT, &a2.FT); + if (comp != 0 || numDigits == 7) + return comp; + return MyCompare(a1.Ns100, a2.Ns100); + } + UInt32 d = 1; + for (unsigned k = numDigits; k < 7; k++) + d *= 10; + const UInt64 v1 = a1.Get_FILETIME_as_UInt64() / d * d; + const UInt64 v2 = a2.Get_FILETIME_as_UInt64() / d * d; + // printf("\ndelta=%d numDigits=%d\n", (unsigned)(v1- v2), numDigits); + return MyCompare(v1, v2); } -static const char *k_Duplicate_inArc_Message = "Duplicate filename in archive:"; -static const char *k_Duplicate_inDir_Message = "Duplicate filename on disk:"; -static const char *k_NotCensoredCollision_Message = "Internal file name collision (file on disk, file in archive):"; -static void ThrowError(const char *message, const UString &s1, const UString &s2) + +static const char * const k_Duplicate_inArc_Message = "Duplicate filename in archive:"; +static const char * const k_Duplicate_inDir_Message = "Duplicate filename on disk:"; +static const char * const k_NotCensoredCollision_Message = "Internal file name collision (file on disk, file in archive):"; + +Z7_ATTR_NORETURN +static +void ThrowError(const char *message, const UString &s1, const UString &s2) { - UString m; - m.SetFromAscii(message); + UString m (message); m.Add_LF(); m += s1; m.Add_LF(); m += s2; throw m; @@ -53,7 +115,7 @@ static void ThrowError(const char *message, const UString &s1, const UString &s2 static int CompareArcItemsBase(const CArcItem &ai1, const CArcItem &ai2) { - int res = CompareFileNames(ai1.Name, ai2.Name); + const int res = CompareFileNames(ai1.Name, ai2.Name); if (res != 0) return res; if (ai1.IsDir != ai2.IsDir) @@ -63,10 +125,10 @@ static int CompareArcItemsBase(const CArcItem &ai1, const CArcItem &ai2) static int CompareArcItems(const unsigned *p1, const unsigned *p2, void *param) { - unsigned i1 = *p1; - unsigned i2 = *p2; + const unsigned i1 = *p1; + const unsigned i2 = *p2; const CObjectVector<CArcItem> &arcItems = *(const CObjectVector<CArcItem> *)param; - int res = CompareArcItemsBase(arcItems[i1], arcItems[i2]); + const int res = CompareArcItemsBase(arcItems[i1], arcItems[i2]); if (res != 0) return res; return MyCompare(i1, i2); @@ -80,8 +142,8 @@ void GetUpdatePairInfoList( { CUIntVector dirIndices, arcIndices; - unsigned numDirItems = dirItems.Items.Size(); - unsigned numArcItems = arcItems.Size(); + const unsigned numDirItems = dirItems.Items.Size(); + const unsigned numArcItems = arcItems.Size(); CIntArr duplicatedArcItem(numArcItems); { @@ -145,18 +207,18 @@ void GetUpdatePairInfoList( if (dirIndex < numDirItems) { - dirIndex2 = dirIndices[dirIndex]; - di = &dirItems.Items[dirIndex2]; + dirIndex2 = (int)dirIndices[dirIndex]; + di = &dirItems.Items[(unsigned)dirIndex2]; } if (arcIndex < numArcItems) { - arcIndex2 = arcIndices[arcIndex]; - ai = &arcItems[arcIndex2]; + arcIndex2 = (int)arcIndices[arcIndex]; + ai = &arcItems[(unsigned)arcIndex2]; compareResult = 1; if (dirIndex < numDirItems) { - compareResult = CompareFileNames(dirNames[dirIndex2], ai->Name); + compareResult = CompareFileNames(dirNames[(unsigned)dirIndex2], ai->Name); if (compareResult == 0) { if (di->IsDir() != ai->IsDir) @@ -167,7 +229,7 @@ void GetUpdatePairInfoList( if (compareResult < 0) { - name = &dirNames[dirIndex2]; + name = &dirNames[(unsigned)dirIndex2]; pair.State = NUpdateArchive::NPairState::kOnlyOnDisk; pair.DirIndex = dirIndex2; dirIndex++; @@ -183,25 +245,28 @@ void GetUpdatePairInfoList( } else { - int dupl = duplicatedArcItem[arcIndex]; + const int dupl = duplicatedArcItem[arcIndex]; if (dupl != 0) - ThrowError(k_Duplicate_inArc_Message, ai->Name, arcItems[arcIndices[arcIndex + dupl]].Name); + ThrowError(k_Duplicate_inArc_Message, ai->Name, arcItems[arcIndices[(unsigned)((int)arcIndex + dupl)]].Name); - name = &dirNames[dirIndex2]; + name = &dirNames[(unsigned)dirIndex2]; if (!ai->Censored) ThrowError(k_NotCensoredCollision_Message, *name, ai->Name); pair.DirIndex = dirIndex2; pair.ArcIndex = arcIndex2; - switch (ai->MTimeDefined ? MyCompareTime( - ai->TimeType != - 1 ? (NFileTimeType::EEnum)ai->TimeType : fileTimeType, - di->MTime, ai->MTime): 0) + int compResult = 0; + if (ai->MTime.Def) + { + compResult = MyCompareTime((unsigned)fileTimeType, di->MTime, ai->MTime); + } + switch (compResult) { case -1: pair.State = NUpdateArchive::NPairState::kNewInArchive; break; case 1: pair.State = NUpdateArchive::NPairState::kOldInArchive; break; default: - pair.State = (ai->SizeDefined && di->Size == ai->Size) ? + pair.State = (ai->Size_Defined && di->Size == ai->Size) ? NUpdateArchive::NPairState::kSameFiles : NUpdateArchive::NPairState::kUnknowNewerFiles; } @@ -210,12 +275,15 @@ void GetUpdatePairInfoList( arcIndex++; } - if ((di && di->IsAltStream) || + if ( + #ifdef _WIN32 + (di && di->IsAltStream) || + #endif (ai && ai->IsAltStream)) { if (prevHostName) { - unsigned hostLen = prevHostName->Len(); + const unsigned hostLen = prevHostName->Len(); if (name->Len() > hostLen) if ((*name)[hostLen] == ':' && CompareFileNames(*prevHostName, name->Left(hostLen)) == 0) pair.HostIndex = prevHostFile; @@ -223,7 +291,7 @@ void GetUpdatePairInfoList( } else { - prevHostFile = updatePairs.Size(); + prevHostFile = (int)updatePairs.Size(); prevHostName = name; } diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/UpdatePair.h b/3rdparty/lzma/CPP/7zip/UI/Common/UpdatePair.h index 296d3b09745..13228b0e012 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/UpdatePair.h +++ b/3rdparty/lzma/CPP/7zip/UI/Common/UpdatePair.h @@ -1,7 +1,7 @@ // UpdatePair.h -#ifndef __UPDATE_PAIR_H -#define __UPDATE_PAIR_H +#ifndef ZIP7_INC_UPDATE_PAIR_H +#define ZIP7_INC_UPDATE_PAIR_H #include "DirItem.h" #include "UpdateAction.h" diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/UpdateProduce.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/UpdateProduce.cpp index e6eabcf148e..e921dc326b6 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/UpdateProduce.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Common/UpdateProduce.cpp @@ -6,7 +6,7 @@ using namespace NUpdateArchive; -static const char *kUpdateActionSetCollision = "Internal collision in update action set"; +static const char * const kUpdateActionSetCollision = "Internal collision in update action set"; void UpdateProduce( const CRecordVector<CUpdatePair> &updatePairs, @@ -28,7 +28,7 @@ void UpdateProduce( { case NPairAction::kIgnore: if (pair.ArcIndex >= 0 && callback) - callback->ShowDeleteFile(pair.ArcIndex); + callback->ShowDeleteFile((unsigned)pair.ArcIndex); continue; case NPairAction::kCopy: @@ -43,7 +43,7 @@ void UpdateProduce( 1) no such alt stream in Disk 2) there is Host file in disk */ - if (updatePairs[pair.HostIndex].DirIndex >= 0) + if (updatePairs[(unsigned)pair.HostIndex].DirIndex >= 0) continue; } } @@ -63,6 +63,8 @@ void UpdateProduce( break; } + up2.IsSameTime = ((unsigned)pair.State == NUpdateArchive::NPairState::kSameFiles); + operationChain.Add(up2); } diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/UpdateProduce.h b/3rdparty/lzma/CPP/7zip/UI/Common/UpdateProduce.h index 64c58cc5772..9db6c1e44b2 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/UpdateProduce.h +++ b/3rdparty/lzma/CPP/7zip/UI/Common/UpdateProduce.h @@ -1,7 +1,7 @@ // UpdateProduce.h -#ifndef __UPDATE_PRODUCE_H -#define __UPDATE_PRODUCE_H +#ifndef ZIP7_INC_UPDATE_PRODUCE_H +#define ZIP7_INC_UPDATE_PRODUCE_H #include "UpdatePair.h" @@ -17,13 +17,14 @@ struct CUpdatePair2 int NewNameIndex; bool IsMainRenameItem; + bool IsSameTime; - void SetAs_NoChangeArcItem(int arcIndex) + void SetAs_NoChangeArcItem(unsigned arcIndex) // int { NewData = NewProps = false; UseArcProps = true; IsAnti = false; - ArcIndex = arcIndex; + ArcIndex = (int)arcIndex; } bool ExistOnDisk() const { return DirIndex != -1; } @@ -37,14 +38,18 @@ struct CUpdatePair2 DirIndex(-1), ArcIndex(-1), NewNameIndex(-1), - IsMainRenameItem(false) + IsMainRenameItem(false), + IsSameTime(false) {} }; -struct IUpdateProduceCallback +Z7_PURE_INTERFACES_BEGIN + +DECLARE_INTERFACE(IUpdateProduceCallback) { virtual HRESULT ShowDeleteFile(unsigned arcIndex) = 0; }; +Z7_PURE_INTERFACES_END void UpdateProduce( const CRecordVector<CUpdatePair> &updatePairs, diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/WorkDir.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/WorkDir.cpp index 284eaa16ac3..cfec63507af 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/WorkDir.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Common/WorkDir.cpp @@ -2,10 +2,8 @@ #include "StdAfx.h" -#include "../../../Common/StringConvert.h" -#include "../../../Common/Wildcard.h" - #include "../../../Windows/FileName.h" +#include "../../../Windows/FileSystem.h" #include "WorkDir.h" @@ -21,10 +19,10 @@ FString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const FString &path, FStr if (workDirInfo.ForRemovableOnly) { mode = NWorkDir::NMode::kCurrent; - FString prefix = path.Left(3); - if (prefix[1] == FTEXT(':') && prefix[2] == FTEXT('\\')) + const FString prefix = path.Left(3); + if (NName::IsDrivePath(prefix)) { - UINT driveType = GetDriveType(GetSystemString(prefix, ::AreFileApisANSI() ? CP_ACP : CP_OEMCP)); + const UINT driveType = NSystem::MyGetDriveType(prefix); if (driveType == DRIVE_CDROM || driveType == DRIVE_REMOVABLE) mode = workDirInfo.Mode; } @@ -38,29 +36,26 @@ FString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const FString &path, FStr } #endif - int pos = path.ReverseFind_PathSepar() + 1; - fileName = path.Ptr(pos); + const int pos = path.ReverseFind_PathSepar() + 1; + fileName = path.Ptr((unsigned)pos); - switch (mode) + FString tempDir; + switch ((int)mode) { case NWorkDir::NMode::kCurrent: - { - return path.Left(pos); - } + tempDir = path.Left((unsigned)pos); + break; case NWorkDir::NMode::kSpecified: - { - FString tempDir = workDirInfo.Path; - NName::NormalizeDirPathPrefix(tempDir); - return tempDir; - } + tempDir = workDirInfo.Path; + break; + // case NWorkDir::NMode::kSystem: default: - { - FString tempDir; if (!MyGetTempPath(tempDir)) throw 141717; - return tempDir; - } + break; } + NName::NormalizeDirPathPrefix(tempDir); + return tempDir; } HRESULT CWorkDirTempFile::CreateTempFile(const FString &originalPath) @@ -68,15 +63,13 @@ HRESULT CWorkDirTempFile::CreateTempFile(const FString &originalPath) NWorkDir::CInfo workDirInfo; workDirInfo.Load(); FString namePart; - FString workDir = GetWorkDir(workDirInfo, originalPath, namePart); + const FString workDir = GetWorkDir(workDirInfo, originalPath, namePart); CreateComplexDir(workDir); - CTempFile tempFile; _outStreamSpec = new COutFileStream; OutStream = _outStreamSpec; if (!_tempFile.Create(workDir + namePart, &_outStreamSpec->File)) { - DWORD error = GetLastError(); - return error ? error : E_FAIL; + return GetLastError_noZero_HRESULT(); } _originalPath = originalPath; return S_OK; @@ -87,8 +80,7 @@ HRESULT CWorkDirTempFile::MoveToOriginal(bool deleteOriginal) OutStream.Release(); if (!_tempFile.MoveTo(_originalPath, deleteOriginal)) { - DWORD error = GetLastError(); - return error ? error : E_FAIL; + return GetLastError_noZero_HRESULT(); } return S_OK; } diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/WorkDir.h b/3rdparty/lzma/CPP/7zip/UI/Common/WorkDir.h index 75850a92b1c..d32ab9d3d2b 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/WorkDir.h +++ b/3rdparty/lzma/CPP/7zip/UI/Common/WorkDir.h @@ -1,7 +1,7 @@ // WorkDir.h -#ifndef __WORK_DIR_H -#define __WORK_DIR_H +#ifndef ZIP7_INC_WORK_DIR_H +#define ZIP7_INC_WORK_DIR_H #include "../../../Windows/FileDir.h" diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/ZipRegistry.h b/3rdparty/lzma/CPP/7zip/UI/Common/ZipRegistry.h index 935f97bbaa4..6bc6977b611 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/ZipRegistry.h +++ b/3rdparty/lzma/CPP/7zip/UI/Common/ZipRegistry.h @@ -1,13 +1,25 @@ // ZipRegistry.h -#ifndef __ZIP_REGISTRY_H -#define __ZIP_REGISTRY_H +#ifndef ZIP7_INC_ZIP_REGISTRY_H +#define ZIP7_INC_ZIP_REGISTRY_H #include "../../../Common/MyTypes.h" #include "../../../Common/MyString.h" +#include "../../Common/MethodProps.h" + #include "ExtractMode.h" +/* +CBoolPair::Def in writing functions means: + if ( CBoolPair::Def ), we write CBoolPair::Val + if ( !CBoolPair::Def ) + { + in NCompression functions we delete registry value + in another functions we do nothing + } +*/ + namespace NExtract { struct CInfo @@ -35,27 +47,87 @@ namespace NExtract namespace NCompression { + struct CMemUse + { + // UString Str; + bool IsDefined; + bool IsPercent; + UInt64 Val; + + CMemUse(): + IsDefined(false), + IsPercent(false), + Val(0) + {} + + void Clear() + { + // Str.Empty(); + IsDefined = false; + IsPercent = false; + Val = 0; + } + + UInt64 GetBytes(UInt64 ramSize) const + { + if (!IsPercent) + return Val; + return Calc_From_Val_Percents(ramSize, Val); + } + void Parse(const UString &s); + }; + struct CFormatOptions { UInt32 Level; UInt32 Dictionary; + // UInt32 DictionaryChain; UInt32 Order; UInt32 BlockLogSize; UInt32 NumThreads; + UInt32 TimePrec; + CBoolPair MTime; + CBoolPair ATime; + CBoolPair CTime; + CBoolPair SetArcMTime; + CSysString FormatID; UString Method; UString Options; UString EncryptionMethod; + UString MemUse; + + void Reset_TimePrec() + { + TimePrec = (UInt32)(Int32)-1; + } + + bool IsSet_TimePrec() const + { + return TimePrec != (UInt32)(Int32)-1; + } + + + void Reset_BlockLogSize() + { + BlockLogSize = (UInt32)(Int32)-1; + } void ResetForLevelChange() { - BlockLogSize = NumThreads = Level = Dictionary = Order = UInt32(-1); + BlockLogSize = NumThreads = Level = Dictionary = Order = (UInt32)(Int32)-1; + // DictionaryChain = (UInt32)(Int32)-1; Method.Empty(); // Options.Empty(); // EncryptionMethod.Empty(); } - CFormatOptions() { ResetForLevelChange(); } + CFormatOptions() + { + // TimePrec = 0; + Reset_TimePrec(); + ResetForLevelChange(); + } }; struct CInfo @@ -63,16 +135,19 @@ namespace NCompression UInt32 Level; bool ShowPassword; bool EncryptHeaders; - UString ArcType; - UStringVector ArcPaths; - - CObjectVector<CFormatOptions> Formats; CBoolPair NtSecurity; CBoolPair AltStreams; CBoolPair HardLinks; CBoolPair SymLinks; + CBoolPair PreserveATime; + + UString ArcType; + UStringVector ArcPaths; + + CObjectVector<CFormatOptions> Formats; + void Save() const; void Load(); }; @@ -92,8 +167,8 @@ namespace NWorkDir struct CInfo { NMode::EEnum Mode; - FString Path; bool ForRemovableOnly; + FString Path; void SetForRemovableOnlyDefault() { ForRemovableOnly = true; } void SetDefault() @@ -114,9 +189,18 @@ struct CContextMenuInfo CBoolPair Cascaded; CBoolPair MenuIcons; CBoolPair ElimDup; - + bool Flags_Def; UInt32 Flags; + UInt32 WriteZone; + + /* + CContextMenuInfo(): + Flags_Def(0), + WriteZone((UInt32)(Int32)-1), + Flags((UInt32)(Int32)-1) + {} + */ void Save() const; void Load(); diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/BenchCon.cpp b/3rdparty/lzma/CPP/7zip/UI/Console/BenchCon.cpp index a7c9e6762c8..113f584a2ef 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/BenchCon.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Console/BenchCon.cpp @@ -7,13 +7,13 @@ #include "BenchCon.h" #include "ConsoleClose.h" -struct CPrintBenchCallback: public IBenchPrintCallback +struct CPrintBenchCallback Z7_final: public IBenchPrintCallback { FILE *_file; - void Print(const char *s); - void NewLine(); - HRESULT CheckBreak(); + void Print(const char *s) Z7_override; + void NewLine() Z7_override; + HRESULT CheckBreak() Z7_override; }; void CPrintBenchCallback::Print(const char *s) diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/BenchCon.h b/3rdparty/lzma/CPP/7zip/UI/Console/BenchCon.h index c9da1de399c..844cc2a799c 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/BenchCon.h +++ b/3rdparty/lzma/CPP/7zip/UI/Console/BenchCon.h @@ -1,7 +1,7 @@ // BenchCon.h -#ifndef __BENCH_CON_H -#define __BENCH_CON_H +#ifndef ZIP7_INC_BENCH_CON_H +#define ZIP7_INC_BENCH_CON_H #include <stdio.h> diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/Console.mak b/3rdparty/lzma/CPP/7zip/UI/Console/Console.mak index 05a07e5ad8a..1a47bfa7ccb 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/Console.mak +++ b/3rdparty/lzma/CPP/7zip/UI/Console/Console.mak @@ -1,3 +1,9 @@ +MY_CONSOLE = 1 + +!IFNDEF UNDER_CE +CFLAGS = $(CFLAGS) -DZ7_LONG_PATH -DZ7_LARGE_PAGES -DZ7_DEVICE_FILE +!ENDIF + CONSOLE_OBJS = \ $O\BenchCon.obj \ $O\ConsoleClose.obj \ @@ -33,4 +39,7 @@ UI_COMMON_OBJS = \ $O\UpdatePair.obj \ $O\UpdateProduce.obj \ -# +C_OBJS = $(C_OBJS) \ + $O\DllSecur.obj \ + +# we need empty line after last line above diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/Console.manifest b/3rdparty/lzma/CPP/7zip/UI/Console/Console.manifest new file mode 100644 index 00000000000..c932b28cec5 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/Console/Console.manifest @@ -0,0 +1,16 @@ +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> +<assemblyIdentity version="1.0.0.0" processorArchitecture="*" name="7z" type="win32"></assemblyIdentity> +<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"> +<security><requestedPrivileges><requestedExecutionLevel level="asInvoker" uiAccess="false"> +</requestedExecutionLevel></requestedPrivileges></security></trustInfo> +<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"><application> +<!-- Vista --> <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> +<!-- Win 7 --> <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> +<!-- Win 8 --> <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> +<!-- Win 8.1 --> <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> +<!-- Win 10 --> <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> +</application></compatibility> +<application xmlns="urn:schemas-microsoft-com:asm.v3"> +<windowsSettings xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings"> +<ws2:longPathAware>true</ws2:longPathAware></windowsSettings></application> +</assembly>
\ No newline at end of file diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/ConsoleClose.cpp b/3rdparty/lzma/CPP/7zip/UI/Console/ConsoleClose.cpp index 703f821395c..9e4c040d3f8 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/ConsoleClose.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Console/ConsoleClose.cpp @@ -4,8 +4,13 @@ #include "ConsoleClose.h" -#if !defined(UNDER_CE) && defined(_WIN32) +#ifndef UNDER_CE + +#ifdef _WIN32 #include "../../../Common/MyWindows.h" +#else +#include <stdlib.h> +#include <signal.h> #endif namespace NConsoleClose { @@ -13,7 +18,8 @@ namespace NConsoleClose { unsigned g_BreakCounter = 0; static const unsigned kBreakAbortThreshold = 2; -#if !defined(UNDER_CE) && defined(_WIN32) +#ifdef _WIN32 + static BOOL WINAPI HandlerRoutine(DWORD ctrlType) { if (ctrlType == CTRL_LOGOFF_EVENT) @@ -37,33 +43,58 @@ static BOOL WINAPI HandlerRoutine(DWORD ctrlType) return FALSE; */ } -#endif - -/* -void CheckCtrlBreak() -{ - if (TestBreakSignal()) - throw CCtrlBreakException(); -} -*/ CCtrlHandlerSetter::CCtrlHandlerSetter() { - #if !defined(UNDER_CE) && defined(_WIN32) if (!SetConsoleCtrlHandler(HandlerRoutine, TRUE)) throw "SetConsoleCtrlHandler fails"; - #endif } CCtrlHandlerSetter::~CCtrlHandlerSetter() { - #if !defined(UNDER_CE) && defined(_WIN32) if (!SetConsoleCtrlHandler(HandlerRoutine, FALSE)) { // warning for throw in destructor. // throw "SetConsoleCtrlHandler fails"; } - #endif } +#else // _WIN32 + +static void HandlerRoutine(int) +{ + g_BreakCounter++; + if (g_BreakCounter < kBreakAbortThreshold) + return; + exit(EXIT_FAILURE); +} + +CCtrlHandlerSetter::CCtrlHandlerSetter() +{ + memo_sig_int = signal(SIGINT, HandlerRoutine); // CTRL-C + if (memo_sig_int == SIG_ERR) + throw "SetConsoleCtrlHandler fails (SIGINT)"; + memo_sig_term = signal(SIGTERM, HandlerRoutine); // for kill -15 (before "kill -9") + if (memo_sig_term == SIG_ERR) + throw "SetConsoleCtrlHandler fails (SIGTERM)"; +} + +CCtrlHandlerSetter::~CCtrlHandlerSetter() +{ + signal(SIGINT, memo_sig_int); // CTRL-C + signal(SIGTERM, memo_sig_term); // kill {pid} +} + +#endif // _WIN32 + +/* +void CheckCtrlBreak() +{ + if (TestBreakSignal()) + throw CCtrlBreakException(); +} +*/ + } + +#endif diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/ConsoleClose.h b/3rdparty/lzma/CPP/7zip/UI/Console/ConsoleClose.h index 11c1631ca71..25c5d0ca668 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/ConsoleClose.h +++ b/3rdparty/lzma/CPP/7zip/UI/Console/ConsoleClose.h @@ -1,32 +1,38 @@ // ConsoleClose.h -#ifndef __CONSOLE_CLOSE_H -#define __CONSOLE_CLOSE_H +#ifndef ZIP7_INC_CONSOLE_CLOSE_H +#define ZIP7_INC_CONSOLE_CLOSE_H namespace NConsoleClose { +class CCtrlBreakException {}; + +#ifdef UNDER_CE + +inline bool TestBreakSignal() { return false; } +struct CCtrlHandlerSetter {}; + +#else + extern unsigned g_BreakCounter; inline bool TestBreakSignal() { - #ifdef UNDER_CE - return false; - #else return (g_BreakCounter != 0); - #endif } -class CCtrlHandlerSetter +class CCtrlHandlerSetter Z7_final { + #ifndef _WIN32 + void (*memo_sig_int)(int); + void (*memo_sig_term)(int); + #endif public: CCtrlHandlerSetter(); - virtual ~CCtrlHandlerSetter(); + ~CCtrlHandlerSetter(); }; -class CCtrlBreakException -{}; - -// void CheckCtrlBreak(); +#endif } diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp b/3rdparty/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp index 8dac7fbc3e9..dd7a2145ae8 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp @@ -11,7 +11,7 @@ #include "../../../Windows/ErrorMsg.h" #include "../../../Windows/PropVariantConv.h" -#ifndef _7ZIP_ST +#ifndef Z7_ST #include "../../../Windows/Synchronization.h" #endif @@ -32,7 +32,7 @@ static HRESULT CheckBreak2() return NConsoleClose::TestBreakSignal() ? E_ABORT : S_OK; } -static const char *kError = "ERROR: "; +static const char * const kError = "ERROR: "; void CExtractScanConsole::StartScanning() @@ -56,18 +56,27 @@ HRESULT CExtractScanConsole::ScanProgress(const CDirItemsStat &st, const FString HRESULT CExtractScanConsole::ScanError(const FString &path, DWORD systemError) { + // 22.00: + // ScanErrors.AddError(path, systemError); + ClosePercentsAndFlush(); if (_se) { - *_se << endl << kError << NError::MyFormatMessage(systemError) << endl << - fs2us(path) << endl << endl; + *_se << endl << kError << NError::MyFormatMessage(systemError) << endl; + _se->NormalizePrint_UString(fs2us(path)); + *_se << endl << endl; _se->Flush(); } return HRESULT_FROM_WIN32(systemError); + + // 22.00: commented + // CommonError(path, systemError, true); + // return S_OK; } +void Print_UInt64_and_String(AString &s, UInt64 val, const char *name); void Print_UInt64_and_String(AString &s, UInt64 val, const char *name) { char temp[32]; @@ -77,6 +86,7 @@ void Print_UInt64_and_String(AString &s, UInt64 val, const char *name) s += name; } +void PrintSize_bytes_Smart(AString &s, UInt64 val); void PrintSize_bytes_Smart(AString &s, UInt64 val) { Print_UInt64_and_String(s, val, "bytes"); @@ -95,6 +105,17 @@ void PrintSize_bytes_Smart(AString &s, UInt64 val) s += ')'; } +static void PrintSize_bytes_Smart_comma(AString &s, UInt64 val) +{ + if (val == (UInt64)(Int64)-1) + return; + s += ", "; + PrintSize_bytes_Smart(s, val); +} + + + +void Print_DirItemsStat(AString &s, const CDirItemsStat &st); void Print_DirItemsStat(AString &s, const CDirItemsStat &st) { if (st.NumDirs != 0) @@ -103,17 +124,49 @@ void Print_DirItemsStat(AString &s, const CDirItemsStat &st) s += ", "; } Print_UInt64_and_String(s, st.NumFiles, st.NumFiles == 1 ? "file" : "files"); - s += ", "; - PrintSize_bytes_Smart(s, st.FilesSize); + PrintSize_bytes_Smart_comma(s, st.FilesSize); if (st.NumAltStreams != 0) { s.Add_LF(); Print_UInt64_and_String(s, st.NumAltStreams, "alternate streams"); - s += ", "; - PrintSize_bytes_Smart(s, st.AltStreamsSize); + PrintSize_bytes_Smart_comma(s, st.AltStreamsSize); + } +} + + +void Print_DirItemsStat2(AString &s, const CDirItemsStat2 &st); +void Print_DirItemsStat2(AString &s, const CDirItemsStat2 &st) +{ + Print_DirItemsStat(s, (CDirItemsStat &)st); + bool needLF = true; + if (st.Anti_NumDirs != 0) + { + if (needLF) + s.Add_LF(); + needLF = false; + Print_UInt64_and_String(s, st.Anti_NumDirs, st.Anti_NumDirs == 1 ? "anti-folder" : "anti-folders"); + } + if (st.Anti_NumFiles != 0) + { + if (needLF) + s.Add_LF(); + else + s += ", "; + needLF = false; + Print_UInt64_and_String(s, st.Anti_NumFiles, st.Anti_NumFiles == 1 ? "anti-file" : "anti-files"); + } + if (st.Anti_NumAltStreams != 0) + { + if (needLF) + s.Add_LF(); + else + s += ", "; + needLF = false; + Print_UInt64_and_String(s, st.Anti_NumAltStreams, "anti-alternate-streams"); } } + void CExtractScanConsole::PrintStat(const CDirItemsStat &st) { if (_so) @@ -130,7 +183,7 @@ void CExtractScanConsole::PrintStat(const CDirItemsStat &st) -#ifndef _7ZIP_ST +#ifndef Z7_ST static NSynchronization::CCriticalSection g_CriticalSection; #define MT_LOCK NSynchronization::CCriticalSectionLock lock(g_CriticalSection); #else @@ -138,33 +191,34 @@ static NSynchronization::CCriticalSection g_CriticalSection; #endif -static const char *kTestString = "T"; -static const char *kExtractString = "-"; -static const char *kSkipString = "."; +static const char * const kTestString = "T"; +static const char * const kExtractString = "-"; +static const char * const kSkipString = "."; +static const char * const kReadString = "H"; -// static const char *kCantAutoRename = "can not create file with auto name\n"; -// static const char *kCantRenameFile = "can not rename existing file\n"; -// static const char *kCantDeleteOutputFile = "can not delete output file "; +// static const char * const kCantAutoRename = "cannot create file with auto name\n"; +// static const char * const kCantRenameFile = "cannot rename existing file\n"; +// static const char * const kCantDeleteOutputFile = "cannot delete output file "; -static const char *kMemoryExceptionMessage = "Can't allocate required memory!"; +static const char * const kMemoryExceptionMessage = "Can't allocate required memory!"; -static const char *kExtracting = "Extracting archive: "; -static const char *kTesting = "Testing archive: "; +static const char * const kExtracting = "Extracting archive: "; +static const char * const kTesting = "Testing archive: "; -static const char *kEverythingIsOk = "Everything is Ok"; -static const char *kNoFiles = "No files to process"; +static const char * const kEverythingIsOk = "Everything is Ok"; +static const char * const kNoFiles = "No files to process"; -static const char *kUnsupportedMethod = "Unsupported Method"; -static const char *kCrcFailed = "CRC Failed"; -static const char *kCrcFailedEncrypted = "CRC Failed in encrypted file. Wrong password?"; -static const char *kDataError = "Data Error"; -static const char *kDataErrorEncrypted = "Data Error in encrypted file. Wrong password?"; -static const char *kUnavailableData = "Unavailable data"; -static const char *kUnexpectedEnd = "Unexpected end of data"; -static const char *kDataAfterEnd = "There are some data after the end of the payload data"; -static const char *kIsNotArc = "Is not archive"; -static const char *kHeadersError = "Headers Error"; -static const char *kWrongPassword = "Wrong password"; +static const char * const kUnsupportedMethod = "Unsupported Method"; +static const char * const kCrcFailed = "CRC Failed"; +static const char * const kCrcFailedEncrypted = "CRC Failed in encrypted file. Wrong password?"; +static const char * const kDataError = "Data Error"; +static const char * const kDataErrorEncrypted = "Data Error in encrypted file. Wrong password?"; +static const char * const kUnavailableData = "Unavailable data"; +static const char * const kUnexpectedEnd = "Unexpected end of data"; +static const char * const kDataAfterEnd = "There are some data after the end of the payload data"; +static const char * const kIsNotArc = "Is not archive"; +static const char * const kHeadersError = "Headers Error"; +static const char * const kWrongPassword = "Wrong password"; static const char * const k_ErrorFlagsMessages[] = { @@ -181,7 +235,7 @@ static const char * const k_ErrorFlagsMessages[] = , "CRC Error" }; -STDMETHODIMP CExtractCallbackConsole::SetTotal(UInt64 size) +Z7_COM7F_IMF(CExtractCallbackConsole::SetTotal(UInt64 size)) { MT_LOCK @@ -193,7 +247,7 @@ STDMETHODIMP CExtractCallbackConsole::SetTotal(UInt64 size) return CheckBreak2(); } -STDMETHODIMP CExtractCallbackConsole::SetCompleted(const UInt64 *completeValue) +Z7_COM7F_IMF(CExtractCallbackConsole::SetCompleted(const UInt64 *completeValue)) { MT_LOCK @@ -206,12 +260,14 @@ STDMETHODIMP CExtractCallbackConsole::SetCompleted(const UInt64 *completeValue) return CheckBreak2(); } -static const char *kTab = " "; +static const char * const kTab = " "; static void PrintFileInfo(CStdOutStream *_so, const wchar_t *path, const FILETIME *ft, const UInt64 *size) { - *_so << kTab << "Path: " << path << endl; - if (size) + *_so << kTab << "Path: "; + _so->NormalizePrint_wstr(path); + *_so << endl; + if (size && *size != (UInt64)(Int64)-1) { AString s; PrintSize_bytes_Smart(s, *size); @@ -220,21 +276,19 @@ static void PrintFileInfo(CStdOutStream *_so, const wchar_t *path, const FILETIM if (ft) { char temp[64]; - FILETIME locTime; - if (FileTimeToLocalFileTime(ft, &locTime)) - if (ConvertFileTimeToString(locTime, temp, true, true)) - *_so << kTab << "Modified: " << temp << endl; + if (ConvertUtcFileTimeToString(*ft, temp, kTimestampPrintLevel_SEC)) + *_so << kTab << "Modified: " << temp << endl; } } -STDMETHODIMP CExtractCallbackConsole::AskOverwrite( +Z7_COM7F_IMF(CExtractCallbackConsole::AskOverwrite( const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize, const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize, - Int32 *answer) + Int32 *answer)) { MT_LOCK - RINOK(CheckBreak2()); + RINOK(CheckBreak2()) ClosePercentsAndFlush(); @@ -248,7 +302,7 @@ STDMETHODIMP CExtractCallbackConsole::AskOverwrite( NUserAnswerMode::EEnum overwriteAnswer = ScanUserYesNoAllQuit(_so); - switch (overwriteAnswer) + switch ((int)overwriteAnswer) { case NUserAnswerMode::kQuit: return E_ABORT; case NUserAnswerMode::kNo: *answer = NOverwriteAnswer::kNo; break; @@ -256,6 +310,8 @@ STDMETHODIMP CExtractCallbackConsole::AskOverwrite( case NUserAnswerMode::kYesAll: *answer = NOverwriteAnswer::kYesToAll; break; case NUserAnswerMode::kYes: *answer = NOverwriteAnswer::kYes; break; case NUserAnswerMode::kAutoRenameAll: *answer = NOverwriteAnswer::kAutoRename; break; + case NUserAnswerMode::kEof: return E_ABORT; + case NUserAnswerMode::kError: return E_FAIL; default: return E_FAIL; } @@ -269,7 +325,7 @@ STDMETHODIMP CExtractCallbackConsole::AskOverwrite( return CheckBreak2(); } -STDMETHODIMP CExtractCallbackConsole::PrepareOperation(const wchar_t *name, Int32 /* isFolder */, Int32 askExtractMode, const UInt64 *position) +Z7_COM7F_IMF(CExtractCallbackConsole::PrepareOperation(const wchar_t *name, Int32 isFolder, Int32 askExtractMode, const UInt64 *position)) { MT_LOCK @@ -283,8 +339,9 @@ STDMETHODIMP CExtractCallbackConsole::PrepareOperation(const wchar_t *name, Int3 case NArchive::NExtract::NAskMode::kExtract: s = kExtractString; break; case NArchive::NExtract::NAskMode::kTest: s = kTestString; break; case NArchive::NExtract::NAskMode::kSkip: s = kSkipString; requiredLevel = 2; break; + case NArchive::NExtract::NAskMode::kReadExternal: s = kReadString; requiredLevel = 0; break; default: s = "???"; requiredLevel = 2; - }; + } bool show2 = (LogLevel >= requiredLevel && _so); @@ -299,7 +356,16 @@ STDMETHODIMP CExtractCallbackConsole::PrepareOperation(const wchar_t *name, Int3 _tempU.Empty(); if (name) + { _tempU = name; + _so->Normalize_UString(_tempU); + // 21.04 + if (isFolder) + { + if (!_tempU.IsEmpty() && _tempU.Back() != WCHAR_PATH_SEPARATOR) + _tempU.Add_PathSepar(); + } + } _so->PrintUString(_tempU, _tempA); if (position) *_so << " <" << *position << ">"; @@ -328,11 +394,11 @@ STDMETHODIMP CExtractCallbackConsole::PrepareOperation(const wchar_t *name, Int3 return CheckBreak2(); } -STDMETHODIMP CExtractCallbackConsole::MessageError(const wchar_t *message) +Z7_COM7F_IMF(CExtractCallbackConsole::MessageError(const wchar_t *message)) { MT_LOCK - RINOK(CheckBreak2()); + RINOK(CheckBreak2()) NumFileErrors_in_Current++; NumFileErrors++; @@ -347,6 +413,7 @@ STDMETHODIMP CExtractCallbackConsole::MessageError(const wchar_t *message) return CheckBreak2(); } +void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, AString &dest); void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, AString &dest) { dest.Empty(); @@ -388,14 +455,12 @@ void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, AString &dest) dest += s; else { - char temp[16]; - ConvertUInt32ToString(opRes, temp); dest += "Error #"; - dest += temp; + dest.Add_UInt32((UInt32)opRes); } } -STDMETHODIMP CExtractCallbackConsole::SetOperationResult(Int32 opRes, Int32 encrypted) +Z7_COM7F_IMF(CExtractCallbackConsole::SetOperationResult(Int32 opRes, Int32 encrypted)) { MT_LOCK @@ -422,7 +487,10 @@ STDMETHODIMP CExtractCallbackConsole::SetOperationResult(Int32 opRes, Int32 encr *_se << s; if (!_currentName.IsEmpty()) - *_se << " : " << _currentName; + { + *_se << " : "; + _se->NormalizePrint_UString(_currentName); + } *_se << endl; _se->Flush(); } @@ -431,7 +499,7 @@ STDMETHODIMP CExtractCallbackConsole::SetOperationResult(Int32 opRes, Int32 encr return CheckBreak2(); } -STDMETHODIMP CExtractCallbackConsole::ReportExtractResult(Int32 opRes, Int32 encrypted, const wchar_t *name) +Z7_COM7F_IMF(CExtractCallbackConsole::ReportExtractResult(Int32 opRes, Int32 encrypted, const wchar_t *name)) { if (opRes != NArchive::NExtract::NOperationResult::kOK) { @@ -444,7 +512,7 @@ STDMETHODIMP CExtractCallbackConsole::ReportExtractResult(Int32 opRes, Int32 enc -#ifndef _NO_CRYPTO +#ifndef Z7_NO_CRYPTO HRESULT CExtractCallbackConsole::SetPassword(const UString &password) { @@ -453,7 +521,7 @@ HRESULT CExtractCallbackConsole::SetPassword(const UString &password) return S_OK; } -STDMETHODIMP CExtractCallbackConsole::CryptoGetTextPassword(BSTR *password) +Z7_COM7F_IMF(CExtractCallbackConsole::CryptoGetTextPassword(BSTR *password)) { COM_TRY_BEGIN MT_LOCK @@ -465,7 +533,7 @@ STDMETHODIMP CExtractCallbackConsole::CryptoGetTextPassword(BSTR *password) HRESULT CExtractCallbackConsole::BeforeOpen(const wchar_t *name, bool testMode) { - RINOK(CheckBreak2()); + RINOK(CheckBreak2()) NumTryArcs++; ThereIsError_in_Current = false; @@ -474,7 +542,11 @@ HRESULT CExtractCallbackConsole::BeforeOpen(const wchar_t *name, bool testMode) ClosePercents_for_so(); if (_so) - *_so << endl << (testMode ? kTesting : kExtracting) << name << endl; + { + *_so << endl << (testMode ? kTesting : kExtracting); + _so->NormalizePrint_wstr(name); + *_so << endl; + } if (NeedPercents()) _percent.Command = "Open"; @@ -488,7 +560,7 @@ static AString GetOpenArcErrorMessage(UInt32 errorFlags) { AString s; - for (unsigned i = 0; i < ARRAY_SIZE(k_ErrorFlagsMessages); i++) + for (unsigned i = 0; i < Z7_ARRAY_SIZE(k_ErrorFlagsMessages); i++) { UInt32 f = (1 << i); if ((errorFlags & f) == 0) @@ -514,6 +586,7 @@ static AString GetOpenArcErrorMessage(UInt32 errorFlags) return s; } +void PrintErrorFlags(CStdOutStream &so, const char *s, UInt32 errorFlags); void PrintErrorFlags(CStdOutStream &so, const char *s, UInt32 errorFlags) { if (errorFlags == 0) @@ -521,29 +594,31 @@ void PrintErrorFlags(CStdOutStream &so, const char *s, UInt32 errorFlags) so << s << endl << GetOpenArcErrorMessage(errorFlags) << endl; } -void Add_Messsage_Pre_ArcType(UString &s, const char *pre, const wchar_t *arcType) +static void Add_Messsage_Pre_ArcType(UString &s, const char *pre, const wchar_t *arcType) { s.Add_LF(); - s.AddAscii(pre); - s.AddAscii(" as ["); + s += pre; + s += " as ["; s += arcType; - s.AddAscii("] archive"); + s += "] archive"; } +void Print_ErrorFormatIndex_Warning(CStdOutStream *_so, const CCodecs *codecs, const CArc &arc); void Print_ErrorFormatIndex_Warning(CStdOutStream *_so, const CCodecs *codecs, const CArc &arc) { const CArcErrorInfo &er = arc.ErrorInfo; - UString s = L"WARNING:\n"; - s += arc.Path; + *_so << "WARNING:\n"; + _so->NormalizePrint_UString(arc.Path); + UString s; if (arc.FormatIndex == er.ErrorFormatIndex) { s.Add_LF(); - s.AddAscii("The archive is open with offset"); + s += "The archive is open with offset"; } else { - Add_Messsage_Pre_ArcType(s, "Can not open the file", codecs->GetFormatNamePtr(er.ErrorFormatIndex)); + Add_Messsage_Pre_ArcType(s, "Cannot open the file", codecs->GetFormatNamePtr(er.ErrorFormatIndex)); Add_Messsage_Pre_ArcType(s, "The file is open", codecs->GetFormatNamePtr(arc.FormatIndex)); } @@ -580,7 +655,10 @@ HRESULT CExtractCallbackConsole::OpenResult( { *_se << endl; if (level != 0) - *_se << arc.Path << endl; + { + _se->NormalizePrint_UString(arc.Path); + *_se << endl; + } } if (errorFlags != 0) @@ -614,7 +692,10 @@ HRESULT CExtractCallbackConsole::OpenResult( { *_so << endl; if (level != 0) - *_so << arc.Path << endl; + { + _so->NormalizePrint_UString(arc.Path); + *_so << endl; + } } if (warningFlags != 0) @@ -658,7 +739,7 @@ HRESULT CExtractCallbackConsole::OpenResult( { if (_so) { - RINOK(Print_OpenArchive_Props(*_so, codecs, arcLink)); + RINOK(Print_OpenArchive_Props(*_so, codecs, arcLink)) *_so << endl; } } @@ -669,9 +750,11 @@ HRESULT CExtractCallbackConsole::OpenResult( _so->Flush(); if (_se) { - *_se << kError << name << endl; - HRESULT res = Print_OpenArchive_Error(*_se, codecs, arcLink); - RINOK(res); + *_se << kError; + _se->NormalizePrint_wstr(name); + *_se << endl; + const HRESULT res = Print_OpenArchive_Error(*_se, codecs, arcLink); + RINOK(res) if (result == S_FALSE) { } @@ -745,7 +828,9 @@ HRESULT CExtractCallbackConsole::ExtractResult(HRESULT result) else { NumArcsWithError++; - if (result == E_ABORT || result == ERROR_DISK_FULL) + if (result == E_ABORT + || result == HRESULT_FROM_WIN32(ERROR_DISK_FULL) + ) return result; if (_se) diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.h b/3rdparty/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.h index dc659521e03..478b293e6ac 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.h +++ b/3rdparty/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.h @@ -1,7 +1,7 @@ // ExtractCallbackConsole.h -#ifndef __EXTRACT_CALLBACK_CONSOLE_H -#define __EXTRACT_CALLBACK_CONSOLE_H +#ifndef ZIP7_INC_EXTRACT_CALLBACK_CONSOLE_H +#define ZIP7_INC_EXTRACT_CALLBACK_CONSOLE_H #include "../../../Common/StdOutStream.h" @@ -15,12 +15,35 @@ #include "OpenCallbackConsole.h" -class CExtractScanConsole: public IDirItemsCallback +/* +struct CErrorPathCodes2 { + FStringVector Paths; + CRecordVector<DWORD> Codes; + + void AddError(const FString &path, DWORD systemError) + { + Paths.Add(path); + Codes.Add(systemError); + } + void Clear() + { + Paths.Clear(); + Codes.Clear(); + } +}; +*/ + +class CExtractScanConsole Z7_final: public IDirItemsCallback +{ + Z7_IFACE_IMP(IDirItemsCallback) + CStdOutStream *_so; CStdOutStream *_se; CPercentPrinter _percent; + // CErrorPathCodes2 ScanErrors; + bool NeedPercents() const { return _percent._so != NULL; } void ClosePercentsAndFlush() @@ -32,6 +55,7 @@ class CExtractScanConsole: public IDirItemsCallback } public: + void Init(CStdOutStream *outStream, CStdOutStream *errorStream, CStdOutStream *percentStream) { _so = outStream; @@ -43,8 +67,6 @@ public: void StartScanning(); - INTERFACE_IDirItemsCallback(;) - void CloseScanning() { if (NeedPercents()) @@ -57,16 +79,36 @@ public: -class CExtractCallbackConsole: +class CExtractCallbackConsole Z7_final: + public IFolderArchiveExtractCallback, public IExtractCallbackUI, // public IArchiveExtractCallbackMessage, public IFolderArchiveExtractCallback2, - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO public ICryptoGetTextPassword, - #endif + #endif public COpenCallbackConsole, public CMyUnknownImp { + Z7_COM_QI_BEGIN2(IFolderArchiveExtractCallback) + // Z7_COM_QI_ENTRY(IArchiveExtractCallbackMessage) + Z7_COM_QI_ENTRY(IFolderArchiveExtractCallback2) + #ifndef Z7_NO_CRYPTO + Z7_COM_QI_ENTRY(ICryptoGetTextPassword) + #endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(IProgress) + Z7_IFACE_COM7_IMP(IFolderArchiveExtractCallback) + Z7_IFACE_IMP(IExtractCallbackUI) + // Z7_IFACE_COM7_IMP(IArchiveExtractCallbackMessage) + Z7_IFACE_COM7_IMP(IFolderArchiveExtractCallback2) + #ifndef Z7_NO_CRYPTO + Z7_IFACE_COM7_IMP(ICryptoGetTextPassword) + #endif + + AString _tempA; UString _tempU; @@ -85,32 +127,7 @@ class CExtractCallbackConsole: if (_so) _so->Flush(); } - public: - MY_QUERYINTERFACE_BEGIN2(IFolderArchiveExtractCallback) - // MY_QUERYINTERFACE_ENTRY(IArchiveExtractCallbackMessage) - MY_QUERYINTERFACE_ENTRY(IFolderArchiveExtractCallback2) - #ifndef _NO_CRYPTO - MY_QUERYINTERFACE_ENTRY(ICryptoGetTextPassword) - #endif - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - STDMETHOD(SetTotal)(UInt64 total); - STDMETHOD(SetCompleted)(const UInt64 *completeValue); - - INTERFACE_IFolderArchiveExtractCallback(;) - - INTERFACE_IExtractCallbackUI(;) - // INTERFACE_IArchiveExtractCallbackMessage(;) - INTERFACE_IFolderArchiveExtractCallback2(;) - - #ifndef _NO_CRYPTO - - STDMETHOD(CryptoGetTextPassword)(BSTR *password); - - #endif - UInt64 NumTryArcs; bool ThereIsError_in_Current; diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/HashCon.cpp b/3rdparty/lzma/CPP/7zip/UI/Console/HashCon.cpp index 6a82daf2eb2..c0e69e26231 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/HashCon.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Console/HashCon.cpp @@ -4,12 +4,14 @@ #include "../../../Common/IntToString.h" +#include "../../../Windows/FileName.h" + #include "ConsoleClose.h" #include "HashCon.h" -static const wchar_t *kEmptyFileAlias = L"[Content]"; +static const char * const kEmptyFileAlias = "[Content]"; -static const char *kScanningMessage = "Scanning"; +static const char * const kScanningMessage = "Scanning"; static HRESULT CheckBreak2() { @@ -33,13 +35,15 @@ HRESULT CHashCallbackConsole::StartScanning() return CheckBreak2(); } -HRESULT CHashCallbackConsole::ScanProgress(const CDirItemsStat &st, const FString &path, bool /* isDir */) +HRESULT CHashCallbackConsole::ScanProgress(const CDirItemsStat &st, const FString &path, bool isDir) { if (NeedPercents()) { _percent.Files = st.NumDirs + st.NumFiles + st.NumAltStreams; _percent.Completed = st.GetTotalBytes(); _percent.FileName = fs2us(path); + if (isDir) + NWindows::NFile::NName::NormalizeDirPathPrefix(_percent.FileName); _percent.Print(); } return CheckBreak2(); @@ -95,7 +99,7 @@ HRESULT CHashCallbackConsole::SetCompleted(const UInt64 *completeValue) static void AddMinuses(AString &s, unsigned num) { for (unsigned i = 0; i < num; i++) - s += '-'; + s.Add_Minus(); } static void AddSpaces_if_Positive(AString &s, int num) @@ -111,6 +115,15 @@ static void SetSpacesAndNul(char *s, unsigned num) s[num] = 0; } +static void SetSpacesAndNul_if_Positive(char *s, int num) +{ + if (num < 0) + return; + for (int i = 0; i < num; i++) + s[i] = ' '; + s[num] = 0; +} + static const unsigned kSizeField_Len = 13; static const unsigned kNameField_Len = 12; @@ -122,61 +135,83 @@ static unsigned GetColumnWidth(unsigned digestSize) return width < kHashColumnWidth_Min ? kHashColumnWidth_Min: width; } -void CHashCallbackConsole::PrintSeparatorLine(const CObjectVector<CHasherState> &hashers) + +AString CHashCallbackConsole::GetFields() const { - _s.Empty(); - - for (unsigned i = 0; i < hashers.Size(); i++) - { - if (i != 0) - _s.Add_Space(); - const CHasherState &h = hashers[i]; - AddMinuses(_s, GetColumnWidth(h.DigestSize)); - } + AString s (PrintFields); + if (s.IsEmpty()) + s = "hsn"; + s.MakeLower_Ascii(); + return s; +} - if (PrintSize) - { - _s.Add_Space(); - AddMinuses(_s, kSizeField_Len); - } - if (PrintName) +void CHashCallbackConsole::PrintSeparatorLine(const CObjectVector<CHasherState> &hashers) +{ + _s.Empty(); + const AString fields = GetFields(); + for (unsigned pos = 0; pos < fields.Len(); pos++) { - AddSpacesBeforeName(); - AddMinuses(_s, kNameField_Len); + const char c = fields[pos]; + if (c == 'h') + { + for (unsigned i = 0; i < hashers.Size(); i++) + { + AddSpace(); + const CHasherState &h = hashers[i]; + AddMinuses(_s, GetColumnWidth(h.DigestSize)); + } + } + else if (c == 's') + { + AddSpace(); + AddMinuses(_s, kSizeField_Len); + } + else if (c == 'n') + { + AddSpacesBeforeName(); + AddMinuses(_s, kNameField_Len); + } } *_so << _s << endl; } + HRESULT CHashCallbackConsole::BeforeFirstFile(const CHashBundle &hb) { if (PrintHeaders && _so) { _s.Empty(); ClosePercents_for_so(); - - FOR_VECTOR (i, hb.Hashers) - { - if (i != 0) - _s.Add_Space(); - const CHasherState &h = hb.Hashers[i]; - _s += h.Name; - AddSpaces_if_Positive(_s, (int)GetColumnWidth(h.DigestSize) - (int)h.Name.Len()); - } - - if (PrintSize) - { - _s.Add_Space(); - const AString s2 = "Size"; - AddSpaces_if_Positive(_s, (int)kSizeField_Len - (int)s2.Len()); - _s += s2; - } - - if (PrintName) + + const AString fields = GetFields(); + for (unsigned pos = 0; pos < fields.Len(); pos++) { - AddSpacesBeforeName(); - _s += "Name"; + const char c = fields[pos]; + if (c == 'h') + { + FOR_VECTOR (i, hb.Hashers) + { + AddSpace(); + const CHasherState &h = hb.Hashers[i]; + _s += h.Name; + AddSpaces_if_Positive(_s, (int)GetColumnWidth(h.DigestSize) - (int)h.Name.Len()); + } + } + + else if (c == 's') + { + AddSpace(); + const AString s2 ("Size"); + AddSpaces_if_Positive(_s, (int)kSizeField_Len - (int)s2.Len()); + _s += s2; + } + else if (c == 'n') + { + AddSpacesBeforeName(); + _s += "Name"; + } } *_so << _s << endl; @@ -191,9 +226,11 @@ HRESULT CHashCallbackConsole::OpenFileError(const FString &path, DWORD systemErr return OpenFileError_Base(path, systemError); } -HRESULT CHashCallbackConsole::GetStream(const wchar_t *name, bool /* isFolder */) +HRESULT CHashCallbackConsole::GetStream(const wchar_t *name, bool isDir) { _fileName = name; + if (isDir) + NWindows::NFile::NName::NormalizeDirPathPrefix(_fileName); if (NeedPercents()) { @@ -208,70 +245,92 @@ HRESULT CHashCallbackConsole::GetStream(const wchar_t *name, bool /* isFolder */ return CheckBreak2(); } + +static const unsigned k_DigestStringSize = k_HashCalc_DigestSize_Max * 2 + k_HashCalc_ExtraSize * 2 + 16; + + + void CHashCallbackConsole::PrintResultLine(UInt64 fileSize, - const CObjectVector<CHasherState> &hashers, unsigned digestIndex, bool showHash) + const CObjectVector<CHasherState> &hashers, unsigned digestIndex, bool showHash, + const AString &path) { ClosePercents_for_so(); _s.Empty(); - - FOR_VECTOR (i, hashers) - { - const CHasherState &h = hashers[i]; - char s[k_HashCalc_DigestSize_Max * 2 + 64]; - s[0] = 0; - if (showHash) - AddHashHexToString(s, h.Digests[digestIndex], h.DigestSize); - SetSpacesAndNul(s + strlen(s), (int)GetColumnWidth(h.DigestSize) - (int)strlen(s)); - if (i != 0) - _s.Add_Space(); - _s += s; - } + const AString fields = GetFields(); - if (PrintSize) + for (unsigned pos = 0; pos < fields.Len(); pos++) { - _s.Add_Space(); - - char s[kSizeField_Len + 32]; - char *p = s; - - if (showHash) + const char c = fields[pos]; + if (c == 'h') { - p = s + kSizeField_Len; - ConvertUInt64ToString(fileSize, p); - int numSpaces = kSizeField_Len - (int)strlen(p); - if (numSpaces > 0) + FOR_VECTOR (i, hashers) { - p -= (unsigned)numSpaces; - for (unsigned i = 0; i < (unsigned)numSpaces; i++) - p[i] = ' '; + AddSpace(); + const CHasherState &h = hashers[i]; + char s[k_DigestStringSize]; + s[0] = 0; + if (showHash) + h.WriteToString(digestIndex, s); + const unsigned len = (unsigned)strlen(s); + SetSpacesAndNul_if_Positive(s + len, (int)GetColumnWidth(h.DigestSize) - (int)len); + _s += s; } } - else + else if (c == 's') + { + AddSpace(); + char s[kSizeField_Len + 32]; + char *p = s; SetSpacesAndNul(s, kSizeField_Len); - - _s += p; + if (showHash) + { + p = s + kSizeField_Len; + ConvertUInt64ToString(fileSize, p); + const int numSpaces = (int)kSizeField_Len - (int)strlen(p); + if (numSpaces > 0) + p -= (unsigned)numSpaces; + } + _s += p; + } + else if (c == 'n') + { + AddSpacesBeforeName(); + _s += path; + } } - - if (PrintName) - AddSpacesBeforeName(); *_so << _s; } + HRESULT CHashCallbackConsole::SetOperationResult(UInt64 fileSize, const CHashBundle &hb, bool showHash) { if (_so) { + AString s; + if (_fileName.IsEmpty()) + s = kEmptyFileAlias; + else + { + UString temp (_fileName); + _so->Normalize_UString(temp); + _so->Convert_UString_to_AString(temp, s); + } + PrintResultLine(fileSize, hb.Hashers, k_HashCalc_Index_Current, showHash, s); + + /* PrintResultLine(fileSize, hb.Hashers, k_HashCalc_Index_Current, showHash); if (PrintName) { if (_fileName.IsEmpty()) *_so << kEmptyFileAlias; else - *_so << _fileName; + _so->NormalizePrint_UString(_fileName); } - *_so << endl; + */ + // if (PrintNewLine) + *_so << endl; } if (NeedPercents()) @@ -303,9 +362,9 @@ static void PrintSum(CStdOutStream &so, const CHasherState &h, unsigned digestIn so << k_DigestTitles[digestIndex]; - char s[k_HashCalc_DigestSize_Max * 2 + 64]; - s[0] = 0; - AddHashHexToString(s, h.Digests[digestIndex], h.DigestSize); + char s[k_DigestStringSize]; + // s[0] = 0; + h.WriteToString(digestIndex, s); so << s << endl; } @@ -332,7 +391,7 @@ void CHashCallbackConsole::PrintProperty(const char *name, UInt64 value) *_so << name << s << endl; } -HRESULT CHashCallbackConsole::AfterLastFile(const CHashBundle &hb) +HRESULT CHashCallbackConsole::AfterLastFile(CHashBundle &hb) { ClosePercents2(); @@ -340,7 +399,7 @@ HRESULT CHashCallbackConsole::AfterLastFile(const CHashBundle &hb) { PrintSeparatorLine(hb.Hashers); - PrintResultLine(hb.FilesSize, hb.Hashers, k_HashCalc_Index_DataSum, true); + PrintResultLine(hb.FilesSize, hb.Hashers, k_HashCalc_Index_DataSum, true, AString()); *_so << endl << endl; diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/HashCon.h b/3rdparty/lzma/CPP/7zip/UI/Console/HashCon.h index 5b30b69a058..ebccb6ff353 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/HashCon.h +++ b/3rdparty/lzma/CPP/7zip/UI/Console/HashCon.h @@ -1,46 +1,56 @@ // HashCon.h -#ifndef __HASH_CON_H -#define __HASH_CON_H +#ifndef ZIP7_INC_HASH_CON_H +#define ZIP7_INC_HASH_CON_H #include "../Common/HashCalc.h" #include "UpdateCallbackConsole.h" -class CHashCallbackConsole: public IHashCallbackUI, public CCallbackConsoleBase +class CHashCallbackConsole Z7_final: + public IHashCallbackUI, + public CCallbackConsoleBase { + Z7_IFACE_IMP(IDirItemsCallback) + Z7_IFACE_IMP(IHashCallbackUI) + UString _fileName; AString _s; + void AddSpace() + { + _s.Add_Space_if_NotEmpty(); + } + void AddSpacesBeforeName() { - _s.Add_Space(); - _s.Add_Space(); + if (!_s.IsEmpty()) + { + _s.Add_Space(); + _s.Add_Space(); + } } void PrintSeparatorLine(const CObjectVector<CHasherState> &hashers); void PrintResultLine(UInt64 fileSize, - const CObjectVector<CHasherState> &hashers, unsigned digestIndex, bool showHash); + const CObjectVector<CHasherState> &hashers, unsigned digestIndex, bool showHash, const AString &path); void PrintProperty(const char *name, UInt64 value); public: bool PrintNameInPercents; - bool PrintHeaders; - - bool PrintSize; - bool PrintName; + // bool PrintSize; + // bool PrintNewLine; // set it too (false), if you need only hash for single file without LF char. + AString PrintFields; + + AString GetFields() const; CHashCallbackConsole(): PrintNameInPercents(true), - PrintHeaders(false), - PrintSize(true), - PrintName(true) + PrintHeaders(false) + // , PrintSize(true), + // , PrintNewLine(true) {} - - ~CHashCallbackConsole() { } - - INTERFACE_IHashCallbackUI(;) }; void PrintHashStat(CStdOutStream &so, const CHashBundle &hb); diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/List.cpp b/3rdparty/lzma/CPP/7zip/UI/Console/List.cpp index 62e813b2834..46819f18bb0 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/List.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Console/List.cpp @@ -124,18 +124,27 @@ static const char * const kPropIdToName[] = , "Read-only" , "Out Name" , "Copy Link" + , "ArcFileName" + , "IsHash" + , "Metadata Changed" + , "User ID" + , "Group ID" + , "Device Major" + , "Device Minor" + , "Dev Major" + , "Dev Minor" }; static const char kEmptyAttribChar = '.'; -static const char *kListing = "Listing archive: "; +static const char * const kListing = "Listing archive: "; -static const char *kString_Files = "files"; -static const char *kString_Dirs = "folders"; -static const char *kString_AltStreams = "alternate streams"; -static const char *kString_Streams = "streams"; +static const char * const kString_Files = "files"; +static const char * const kString_Dirs = "folders"; +static const char * const kString_AltStreams = "alternate streams"; +static const char * const kString_Streams = "streams"; -static const char *kError = "ERROR: "; +static const char * const kError = "ERROR: "; static void GetAttribString(UInt32 wa, bool isDir, bool allAttribs, char *s) { @@ -303,22 +312,18 @@ struct CListUInt64Def void Add(const CListUInt64Def &v) { if (v.Def) Add(v.Val); } }; -struct CListFileTimeDef -{ - FILETIME Val; - bool Def; - CListFileTimeDef(): Def(false) { Val.dwLowDateTime = 0; Val.dwHighDateTime = 0; } +struct CListFileTimeDef: public CArcTime +{ void Update(const CListFileTimeDef &t) { - if (t.Def && (!Def || CompareFileTime(&Val, &t.Val) < 0)) - { - Val = t.Val; - Def = true; - } + if (t.Def && (!Def || CompareWith(t) < 0)) + (*this) = t; } }; + + struct CListStat { CListUInt64Def Size; @@ -351,7 +356,7 @@ struct CListStat2 AltStreams.Update(st.AltStreams); NumDirs += st.NumDirs; } - const UInt64 GetNumStreams() const { return MainFiles.NumFiles + AltStreams.NumFiles; } + UInt64 GetNumStreams() const { return MainFiles.NumFiles + AltStreams.NumFiles; } CListStat &GetStat(bool altStreamsMode) { return altStreamsMode ? AltStreams : MainFiles; } }; @@ -402,13 +407,13 @@ void CFieldPrinter::Init(const CFieldInfoInit *standardFieldTable, unsigned numI for (k = 0; k < fii.PrefixSpacesWidth; k++) LinesString.Add_Space(); for (k = 0; k < fii.Width; k++) - LinesString += '-'; + LinesString.Add_Minus(); } } static void GetPropName(PROPID propID, const wchar_t *name, AString &nameA, UString &nameU) { - if (propID < ARRAY_SIZE(kPropIdToName)) + if (propID < Z7_ARRAY_SIZE(kPropIdToName)) { nameA = kPropIdToName[propID]; return; @@ -417,9 +422,8 @@ static void GetPropName(PROPID propID, const wchar_t *name, AString &nameA, UStr nameU = name; else { - char s[16]; - ConvertUInt32ToString(propID, s); - nameA = s; + nameA.Empty(); + nameA.Add_UInt32(propID); } } @@ -429,7 +433,7 @@ void CFieldPrinter::AddProp(const wchar_t *name, PROPID propID, bool isRawProp) f.PropID = propID; f.IsRawProp = isRawProp; GetPropName(propID, name, f.NameA, f.NameU); - f.NameU.AddAscii(" = "); + f.NameU += " = "; if (!f.NameA.IsEmpty()) f.NameA += " = "; else @@ -453,13 +457,13 @@ void CFieldPrinter::AddProp(const wchar_t *name, PROPID propID, bool isRawProp) HRESULT CFieldPrinter::AddMainProps(IInArchive *archive) { UInt32 numProps; - RINOK(archive->GetNumberOfProperties(&numProps)); + RINOK(archive->GetNumberOfProperties(&numProps)) for (UInt32 i = 0; i < numProps; i++) { CMyComBSTR name; PROPID propID; VARTYPE vt; - RINOK(archive->GetPropertyInfo(i, &name, &propID, &vt)); + RINOK(archive->GetPropertyInfo(i, &name, &propID, &vt)) AddProp(name, propID, false); } return S_OK; @@ -468,12 +472,12 @@ HRESULT CFieldPrinter::AddMainProps(IInArchive *archive) HRESULT CFieldPrinter::AddRawProps(IArchiveGetRawProps *getRawProps) { UInt32 numProps; - RINOK(getRawProps->GetNumRawProps(&numProps)); + RINOK(getRawProps->GetNumRawProps(&numProps)) for (UInt32 i = 0; i < numProps; i++) { CMyComBSTR name; PROPID propID; - RINOK(getRawProps->GetRawPropInfo(i, &name, &propID)); + RINOK(getRawProps->GetRawPropInfo(i, &name, &propID)) AddProp(name, propID, true); } return S_OK; @@ -494,22 +498,31 @@ void CFieldPrinter::PrintTitleLines() g_StdOut << LinesString; } -static void PrintTime(char *dest, const FILETIME *ft) +static void PrintTime(char *dest, const CListFileTimeDef &t, bool showNS) { *dest = 0; - if (ft->dwLowDateTime == 0 && ft->dwHighDateTime == 0) + if (t.IsZero()) return; - FILETIME locTime; - if (!FileTimeToLocalFileTime(ft, &locTime)) - throw 20121211; - ConvertFileTimeToString(locTime, dest, true, true); + int prec = kTimestampPrintLevel_SEC; + if (showNS) + { + prec = kTimestampPrintLevel_NTFS; + if (t.Prec != 0) + { + prec = t.GetNumDigits(); + if (prec < kTimestampPrintLevel_DAY) + prec = kTimestampPrintLevel_NTFS; + } + } + + ConvertUtcFileTimeToString2(t.FT, t.Ns100, dest, prec); } -#ifndef _SFX +#ifndef Z7_SFX static inline char GetHex(Byte value) { - return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10))); + return (char)((value < 10) ? ('0' + value) : ('a' + (value - 10))); } static void HexToString(char *dest, const Byte *data, UInt32 size) @@ -564,7 +577,7 @@ HRESULT CFieldPrinter::PrintItemInfo(UInt32 index, const CListStat &st) { if (!techMode) g_StdOut << temp; - g_StdOut.PrintUString(FilePath, TempAString); + g_StdOut.NormalizePrint_UString(FilePath, TempWString, TempAString); if (techMode) g_StdOut << MY_ENDL; continue; @@ -574,12 +587,12 @@ HRESULT CFieldPrinter::PrintItemInfo(UInt32 index, const CListStat &st) if (f.IsRawProp) { - #ifndef _SFX + #ifndef Z7_SFX const void *data; UInt32 dataSize; UInt32 propType; - RINOK(Arc->GetRawProps->GetRawProp(index, f.PropID, &data, &dataSize, &propType)); + RINOK(Arc->GetRawProps->GetRawProp(index, f.PropID, &data, &dataSize, &propType)) if (dataSize != 0) { @@ -589,7 +602,7 @@ HRESULT CFieldPrinter::PrintItemInfo(UInt32 index, const CListStat &st) { if (propType != NPropDataType::kRaw) return E_FAIL; - #ifndef _SFX + #ifndef Z7_SFX ConvertNtSecureToString((const Byte *)data, dataSize, TempAString); g_StdOut << TempAString; needPrint = false; @@ -635,9 +648,15 @@ HRESULT CFieldPrinter::PrintItemInfo(UInt32 index, const CListStat &st) { case kpidSize: if (st.Size.Def) prop = st.Size.Val; break; case kpidPackSize: if (st.PackSize.Def) prop = st.PackSize.Val; break; - case kpidMTime: if (st.MTime.Def) prop = st.MTime.Val; break; + case kpidMTime: + { + const CListFileTimeDef &mtime = st.MTime; + if (mtime.Def) + prop.SetAsTimeFrom_FT_Prec_Ns100(mtime.FT, mtime.Prec, mtime.Ns100); + break; + } default: - RINOK(Arc->Archive->GetProperty(index, f.PropID, &prop)); + RINOK(Arc->Archive->GetProperty(index, f.PropID, &prop)) } if (f.PropID == kpidAttrib && (prop.vt == VT_EMPTY || prop.vt == VT_UI4)) { @@ -657,7 +676,9 @@ HRESULT CFieldPrinter::PrintItemInfo(UInt32 index, const CListStat &st) } else if (prop.vt == VT_FILETIME) { - PrintTime(temp + tempPos, &prop.filetime); + CListFileTimeDef t; + t.Set_From_Prop(prop); + PrintTime(temp + tempPos, t, techMode); if (techMode) g_StdOut << temp + tempPos; else @@ -675,9 +696,10 @@ HRESULT CFieldPrinter::PrintItemInfo(UInt32 index, const CListStat &st) else if (prop.vt == VT_BSTR) { TempWString.SetFromBstr(prop.bstrVal); + // do we need multi-line support here ? + g_StdOut.Normalize_UString(TempWString); if (techMode) { - // replace CR/LF here. g_StdOut.PrintUString(TempWString, TempAString); } else @@ -686,7 +708,7 @@ HRESULT CFieldPrinter::PrintItemInfo(UInt32 index, const CListStat &st) else { char s[64]; - ConvertPropertyToShortString(s, prop, f.PropID); + ConvertPropertyToShortString2(s, prop, f.PropID); if (techMode) g_StdOut << s; else @@ -729,7 +751,7 @@ void CFieldPrinter::PrintSum(const CListStat &st, UInt64 numDirs, const char *st char s[64]; s[0] = 0; if (st.MTime.Def) - PrintTime(s, &st.MTime.Val); + PrintTime(s, st.MTime, false); // showNS PrintString(f.TextAdjustment, f.Width, s); } else if (f.PropID == kpidPath) @@ -754,7 +776,7 @@ void CFieldPrinter::PrintSum(const CListStat2 &stat2) PrintSum(stat2.MainFiles, stat2.NumDirs, kString_Files); if (stat2.AltStreams.NumFiles != 0) { - PrintSum(stat2.AltStreams, 0, kString_AltStreams);; + PrintSum(stat2.AltStreams, 0, kString_AltStreams); CListStat st = stat2.MainFiles; st.Update(stat2.AltStreams); PrintSum(st, 0, kString_Streams); @@ -766,23 +788,21 @@ static HRESULT GetUInt64Value(IInArchive *archive, UInt32 index, PROPID propID, value.Val = 0; value.Def = false; CPropVariant prop; - RINOK(archive->GetProperty(index, propID, &prop)); + RINOK(archive->GetProperty(index, propID, &prop)) value.Def = ConvertPropVariantToUInt64(prop, value.Val); return S_OK; } static HRESULT GetItemMTime(IInArchive *archive, UInt32 index, CListFileTimeDef &t) { - t.Val.dwLowDateTime = 0; - t.Val.dwHighDateTime = 0; - t.Def = false; + /* maybe we could call CArc::GetItemMTime(UInt32 index, CArcTime &ft, bool &defined) here + that can set default timestamp, if not defined */ + t.Clear(); + // t.Def = false; CPropVariant prop; - RINOK(archive->GetProperty(index, kpidMTime, &prop)); + RINOK(archive->GetProperty(index, kpidMTime, &prop)) if (prop.vt == VT_FILETIME) - { - t.Val = prop.filetime; - t.Def = true; - } + t.Set_From_Prop(prop); else if (prop.vt != VT_EMPTY) return E_FAIL; return S_OK; @@ -797,7 +817,7 @@ static void PrintPropName_and_Eq(CStdOutStream &so, PROPID propID) { const char *s; char temp[16]; - if (propID < ARRAY_SIZE(kPropIdToName)) + if (propID < Z7_ARRAY_SIZE(kPropIdToName)) s = kPropIdToName[propID]; else { @@ -819,32 +839,89 @@ static void PrintPropNameAndNumber_Signed(CStdOutStream &so, PROPID propID, Int6 so << val << endl; } -static void PrintPropPair(CStdOutStream &so, const char *name, const wchar_t *val) + +static void UString_Replace_CRLF_to_LF(UString &s) { - so << name << " = " << val << endl; + // s.Replace(L"\r\n", L"\n"); + wchar_t *src = s.GetBuf(); + wchar_t *dest = src; + for (;;) + { + wchar_t c = *src++; + if (c == 0) + break; + if (c == '\r' && *src == '\n') + { + src++; + c = '\n'; + } + *dest++ = c; + } + s.ReleaseBuf_SetEnd((unsigned)(dest - s.GetBuf())); +} + + +static void PrintPropVal_MultiLine(CStdOutStream &so, const wchar_t *val) +{ + UString s (val); + if (s.Find(L'\n') >= 0) + { + so << endl; + so << "{"; + so << endl; + UString_Replace_CRLF_to_LF(s); + so.Normalize_UString_LF_Allowed(s); + so << s; + so << endl; + so << "}"; + } + else + { + so.Normalize_UString(s); + so << s; + } + so << endl; +} + + +static void PrintPropPair(CStdOutStream &so, const char *name, const wchar_t *val, bool multiLine) +{ + so << name << " = "; + if (multiLine) + { + PrintPropVal_MultiLine(so, val); + return; + } + UString s (val); + so.Normalize_UString(s); + so << s; + so << endl; } static void PrintPropertyPair2(CStdOutStream &so, PROPID propID, const wchar_t *name, const CPropVariant &prop) { UString s; - ConvertPropertyToString(s, prop, propID); + const int levelTopLimit = 9; // 1ns level + ConvertPropertyToString2(s, prop, propID, levelTopLimit); if (!s.IsEmpty()) { AString nameA; UString nameU; GetPropName(propID, name, nameA, nameU); if (!nameA.IsEmpty()) - PrintPropPair(so, nameA, s); + so << nameA; else - so << nameU << " = " << s << endl; + so << nameU; + so << " = "; + PrintPropVal_MultiLine(so, s); } } static HRESULT PrintArcProp(CStdOutStream &so, IInArchive *archive, PROPID propID, const wchar_t *name) { CPropVariant prop; - RINOK(archive->GetArchiveProperty(propID, &prop)); + RINOK(archive->GetArchiveProperty(propID, &prop)) PrintPropertyPair2(so, propID, name, prop); return S_OK; } @@ -852,7 +929,7 @@ static HRESULT PrintArcProp(CStdOutStream &so, IInArchive *archive, PROPID propI static void PrintArcTypeError(CStdOutStream &so, const UString &type, bool isWarning) { so << "Open " << (isWarning ? "WARNING" : "ERROR") - << ": Can not open the file as [" + << ": Cannot open the file as [" << type << "] archive" << endl; @@ -866,13 +943,14 @@ static void ErrorInfo_Print(CStdOutStream &so, const CArcErrorInfo &er) { PrintErrorFlags(so, "ERRORS:", er.GetErrorFlags()); if (!er.ErrorMessage.IsEmpty()) - PrintPropPair(so, "ERROR", er.ErrorMessage); + PrintPropPair(so, "ERROR", er.ErrorMessage, true); PrintErrorFlags(so, "WARNINGS:", er.GetWarningFlags()); if (!er.WarningMessage.IsEmpty()) - PrintPropPair(so, "WARNING", er.WarningMessage); + PrintPropPair(so, "WARNING", er.WarningMessage, true); } +HRESULT Print_OpenArchive_Props(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink); HRESULT Print_OpenArchive_Props(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink) { FOR_VECTOR (r, arcLink.Arcs) @@ -881,7 +959,7 @@ HRESULT Print_OpenArchive_Props(CStdOutStream &so, const CCodecs *codecs, const const CArcErrorInfo &er = arc.ErrorInfo; so << "--\n"; - PrintPropPair(so, "Path", arc.Path); + PrintPropPair(so, "Path", arc.Path, false); if (er.ErrorFormatIndex >= 0) { if (er.ErrorFormatIndex == arc.FormatIndex) @@ -889,7 +967,7 @@ HRESULT Print_OpenArchive_Props(CStdOutStream &so, const CCodecs *codecs, const else PrintArcTypeError(so, codecs->GetFormatNamePtr(er.ErrorFormatIndex), true); } - PrintPropPair(so, "Type", codecs->GetFormatNamePtr(arc.FormatIndex)); + PrintPropPair(so, "Type", codecs->GetFormatNamePtr(arc.FormatIndex), false); ErrorInfo_Print(so, er); @@ -897,20 +975,20 @@ HRESULT Print_OpenArchive_Props(CStdOutStream &so, const CCodecs *codecs, const if (offset != 0) PrintPropNameAndNumber_Signed(so, kpidOffset, offset); IInArchive *archive = arc.Archive; - RINOK(PrintArcProp(so, archive, kpidPhySize, NULL)); + RINOK(PrintArcProp(so, archive, kpidPhySize, NULL)) if (er.TailSize != 0) PrintPropNameAndNumber(so, kpidTailSize, er.TailSize); { UInt32 numProps; - RINOK(archive->GetNumberOfArchiveProperties(&numProps)); + RINOK(archive->GetNumberOfArchiveProperties(&numProps)) for (UInt32 j = 0; j < numProps; j++) { CMyComBSTR name; PROPID propID; VARTYPE vt; - RINOK(archive->GetArchivePropertyInfo(j, &name, &propID, &vt)); - RINOK(PrintArcProp(so, archive, propID, name)); + RINOK(archive->GetArchivePropertyInfo(j, &name, &propID, &vt)) + RINOK(PrintArcProp(so, archive, propID, name)) } } @@ -926,9 +1004,9 @@ HRESULT Print_OpenArchive_Props(CStdOutStream &so, const CCodecs *codecs, const CMyComBSTR name; PROPID propID; VARTYPE vt; - RINOK(archive->GetPropertyInfo(j, &name, &propID, &vt)); + RINOK(archive->GetPropertyInfo(j, &name, &propID, &vt)) CPropVariant prop; - RINOK(archive->GetProperty(mainIndex, propID, &prop)); + RINOK(archive->GetProperty(mainIndex, propID, &prop)) PrintPropertyPair2(so, propID, name, prop); } } @@ -937,21 +1015,23 @@ HRESULT Print_OpenArchive_Props(CStdOutStream &so, const CCodecs *codecs, const return S_OK; } +HRESULT Print_OpenArchive_Error(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink); HRESULT Print_OpenArchive_Error(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink) { - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO if (arcLink.PasswordWasAsked) - so << "Can not open encrypted archive. Wrong password?"; + so << "Cannot open encrypted archive. Wrong password?"; else #endif { if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0) { - so << arcLink.NonOpen_ArcPath << endl; - PrintArcTypeError(so, codecs->Formats[arcLink.NonOpen_ErrorInfo.ErrorFormatIndex].Name, false); + so.NormalizePrint_UString(arcLink.NonOpen_ArcPath); + so << endl; + PrintArcTypeError(so, codecs->Formats[(unsigned)arcLink.NonOpen_ErrorInfo.ErrorFormatIndex].Name, false); } else - so << "Can not open the file as archive"; + so << "Cannot open the file as archive"; } so << endl; @@ -963,7 +1043,9 @@ HRESULT Print_OpenArchive_Error(CStdOutStream &so, const CCodecs *codecs, const bool CensorNode_CheckPath(const NWildcard::CCensorNode &node, const CReadArcItem &item); -HRESULT ListArchives(CCodecs *codecs, +HRESULT ListArchives( + const CListOptions &listOptions, + CCodecs *codecs, const CObjectVector<COpenType> &types, const CIntVector &excludedFormats, bool stdInMode, @@ -971,10 +1053,10 @@ HRESULT ListArchives(CCodecs *codecs, bool processAltStreams, bool showAltStreams, const NWildcard::CCensorNode &wildcardCensor, bool enableHeaders, bool techMode, - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO bool &passwordEnabled, UString &password, #endif - #ifndef _SFX + #ifndef Z7_SFX const CObjectVector<CProperty> *props, #endif UInt64 &numErrors, @@ -987,7 +1069,7 @@ HRESULT ListArchives(CCodecs *codecs, CFieldPrinter fp; if (!techMode) - fp.Init(kStandardFieldTable, ARRAY_SIZE(kStandardFieldTable)); + fp.Init(kStandardFieldTable, Z7_ARRAY_SIZE(kStandardFieldTable)); CListStat2 stat2total; @@ -1011,22 +1093,31 @@ HRESULT ListArchives(CCodecs *codecs, if (!stdInMode) { NFile::NFind::CFileInfo fi; - if (!fi.Find(us2fs(arcPath))) + if (!fi.Find_FollowLink(us2fs(arcPath))) { DWORD errorCode = GetLastError(); if (errorCode == 0) errorCode = ERROR_FILE_NOT_FOUND; - lastError = HRESULT_FROM_WIN32(lastError);; + lastError = HRESULT_FROM_WIN32(errorCode); g_StdOut.Flush(); - *g_ErrStream << endl << kError << NError::MyFormatMessage(errorCode) << - endl << arcPath << endl << endl; + if (g_ErrStream) + { + *g_ErrStream << endl << kError << NError::MyFormatMessage(errorCode) << endl; + g_ErrStream->NormalizePrint_UString(arcPath); + *g_ErrStream << endl << endl; + } numErrors++; continue; } if (fi.IsDir()) { g_StdOut.Flush(); - *g_ErrStream << endl << kError << arcPath << " is not a file" << endl << endl; + if (g_ErrStream) + { + *g_ErrStream << endl << kError; + g_ErrStream->NormalizePrint_UString(arcPath); + *g_ErrStream << " is not a file" << endl << endl; + } numErrors++; continue; } @@ -1039,7 +1130,7 @@ HRESULT ListArchives(CCodecs *codecs, COpenCallbackConsole openCallback; openCallback.Init(&g_StdOut, g_ErrStream, NULL); - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO openCallback.PasswordIsDefined = passwordEnabled; openCallback.Password = password; @@ -1053,7 +1144,7 @@ HRESULT ListArchives(CCodecs *codecs, */ COpenOptions options; - #ifndef _SFX + #ifndef Z7_SFX options.props = props; #endif options.codecs = codecs; @@ -1065,7 +1156,9 @@ HRESULT ListArchives(CCodecs *codecs, if (enableHeaders) { - g_StdOut << endl << kListing << arcPath << endl << endl; + g_StdOut << endl << kListing; + g_StdOut.NormalizePrint_UString(arcPath); + g_StdOut << endl << endl; } HRESULT result = arcLink.Open_Strict(options, &openCallback); @@ -1074,22 +1167,28 @@ HRESULT ListArchives(CCodecs *codecs, { if (result == E_ABORT) return result; + if (result != S_FALSE) + lastError = result; g_StdOut.Flush(); - *g_ErrStream << endl << kError << arcPath << " : "; - if (result == S_FALSE) + if (g_ErrStream) { - Print_OpenArchive_Error(*g_ErrStream, codecs, arcLink); - } - else - { - lastError = result; - *g_ErrStream << "opening : "; - if (result == E_OUTOFMEMORY) - *g_ErrStream << "Can't allocate required memory"; + *g_ErrStream << endl << kError; + g_ErrStream->NormalizePrint_UString(arcPath); + *g_ErrStream << " : "; + if (result == S_FALSE) + { + Print_OpenArchive_Error(*g_ErrStream, codecs, arcLink); + } else - *g_ErrStream << NError::MyFormatMessage(result); + { + *g_ErrStream << "opening : "; + if (result == E_OUTOFMEMORY) + *g_ErrStream << "Can't allocate required memory"; + else + *g_ErrStream << NError::MyFormatMessage(result); + } + *g_ErrStream << endl; } - *g_ErrStream << endl; numErrors++; continue; } @@ -1132,7 +1231,7 @@ HRESULT ListArchives(CCodecs *codecs, if (enableHeaders) { - RINOK(Print_OpenArchive_Props(g_StdOut, codecs, arcLink)); + RINOK(Print_OpenArchive_Props(g_StdOut, codecs, arcLink)) g_StdOut << endl; if (techMode) @@ -1154,17 +1253,17 @@ HRESULT ListArchives(CCodecs *codecs, if (techMode) { fp.Clear(); - RINOK(fp.AddMainProps(archive)); + RINOK(fp.AddMainProps(archive)) if (arc.GetRawProps) { - RINOK(fp.AddRawProps(arc.GetRawProps)); + RINOK(fp.AddRawProps(arc.GetRawProps)) } } CListStat2 stat2; UInt32 numItems; - RINOK(archive->GetNumberOfItems(&numItems)); + RINOK(archive->GetNumberOfItems(&numItems)) CReadArcItem item; UStringVector pathParts; @@ -1174,16 +1273,16 @@ HRESULT ListArchives(CCodecs *codecs, if (NConsoleClose::TestBreakSignal()) return E_ABORT; - HRESULT res = arc.GetItemPath2(i, fp.FilePath); + HRESULT res = arc.GetItem_Path2(i, fp.FilePath); if (stdInMode && res == E_INVALIDARG) break; - RINOK(res); + RINOK(res) if (arc.Ask_Aux) { bool isAux; - RINOK(Archive_IsItem_Aux(archive, i, isAux)); + RINOK(Archive_IsItem_Aux(archive, i, isAux)) if (isAux) continue; } @@ -1191,24 +1290,27 @@ HRESULT ListArchives(CCodecs *codecs, bool isAltStream = false; if (arc.Ask_AltStream) { - RINOK(Archive_IsItem_AltStream(archive, i, isAltStream)); + RINOK(Archive_IsItem_AltStream(archive, i, isAltStream)) if (isAltStream && !processAltStreams) continue; } - RINOK(Archive_IsItem_Dir(archive, i, fp.IsDir)); + RINOK(Archive_IsItem_Dir(archive, i, fp.IsDir)) + + if (fp.IsDir ? listOptions.ExcludeDirItems : listOptions.ExcludeFileItems) + continue; if (!allFilesAreAllowed) { if (isAltStream) { - RINOK(arc.GetItem(i, item)); + RINOK(arc.GetItem(i, item)) if (!CensorNode_CheckPath(wildcardCensor, item)) continue; } else { - SplitPathToParts(fp.FilePath, pathParts);; + SplitPathToParts(fp.FilePath, pathParts); bool include; if (!wildcardCensor.CheckPathVect(pathParts, !fp.IsDir, include)) continue; @@ -1219,9 +1321,9 @@ HRESULT ListArchives(CCodecs *codecs, CListStat st; - RINOK(GetUInt64Value(archive, i, kpidSize, st.Size)); - RINOK(GetUInt64Value(archive, i, kpidPackSize, st.PackSize)); - RINOK(GetItemMTime(archive, i, st.MTime)); + RINOK(GetUInt64Value(archive, i, kpidSize, st.Size)) + RINOK(GetUInt64Value(archive, i, kpidPackSize, st.PackSize)) + RINOK(GetItemMTime(archive, i, st.MTime)) if (fp.IsDir) stat2.NumDirs++; @@ -1231,7 +1333,7 @@ HRESULT ListArchives(CCodecs *codecs, if (isAltStream && !showAltStreams) continue; - RINOK(fp.PrintItemInfo(i, st)); + RINOK(fp.PrintItemInfo(i, st)) } UInt64 numStreams = stat2.GetNumStreams(); @@ -1259,8 +1361,8 @@ HRESULT ListArchives(CCodecs *codecs, if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0) { g_StdOut << "----------\n"; - PrintPropPair(g_StdOut, "Path", arcLink.NonOpen_ArcPath); - PrintArcTypeError(g_StdOut, codecs->Formats[arcLink.NonOpen_ErrorInfo.ErrorFormatIndex].Name, false); + PrintPropPair(g_StdOut, "Path", arcLink.NonOpen_ArcPath, false); + PrintArcTypeError(g_StdOut, codecs->Formats[(unsigned)arcLink.NonOpen_ErrorInfo.ErrorFormatIndex].Name, false); } } diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/List.h b/3rdparty/lzma/CPP/7zip/UI/Console/List.h index 462c4710375..4969c3e23bb 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/List.h +++ b/3rdparty/lzma/CPP/7zip/UI/Console/List.h @@ -1,13 +1,26 @@ // List.h -#ifndef __LIST_H -#define __LIST_H +#ifndef ZIP7_INC_LIST_H +#define ZIP7_INC_LIST_H #include "../../../Common/Wildcard.h" #include "../Common/LoadCodecs.h" -HRESULT ListArchives(CCodecs *codecs, +struct CListOptions +{ + bool ExcludeDirItems; + bool ExcludeFileItems; + + CListOptions(): + ExcludeDirItems(false), + ExcludeFileItems(false) + {} +}; + +HRESULT ListArchives( + const CListOptions &listOptions, + CCodecs *codecs, const CObjectVector<COpenType> &types, const CIntVector &excludedFormats, bool stdInMode, @@ -15,12 +28,12 @@ HRESULT ListArchives(CCodecs *codecs, bool processAltStreams, bool showAltStreams, const NWildcard::CCensorNode &wildcardCensor, bool enableHeaders, bool techMode, - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO bool &passwordEnabled, UString &password, - #endif - #ifndef _SFX + #endif + #ifndef Z7_SFX const CObjectVector<CProperty> *props, - #endif + #endif UInt64 &errors, UInt64 &numWarnings); diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/Main.cpp b/3rdparty/lzma/CPP/7zip/UI/Console/Main.cpp index 50652555de7..eb9e2a80042 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/Main.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Console/Main.cpp @@ -5,37 +5,63 @@ #include "../../../Common/MyWindows.h" #ifdef _WIN32 + +#ifndef Z7_OLD_WIN_SDK + +#if defined(__MINGW32__) || defined(__MINGW64__) +#include <psapi.h> +#else #include <Psapi.h> #endif -#include "../../../../C/CpuArch.h" +#else // Z7_OLD_WIN_SDK + +typedef struct _PROCESS_MEMORY_COUNTERS { + DWORD cb; + DWORD PageFaultCount; + SIZE_T PeakWorkingSetSize; + SIZE_T WorkingSetSize; + SIZE_T QuotaPeakPagedPoolUsage; + SIZE_T QuotaPagedPoolUsage; + SIZE_T QuotaPeakNonPagedPoolUsage; + SIZE_T QuotaNonPagedPoolUsage; + SIZE_T PagefileUsage; + SIZE_T PeakPagefileUsage; +} PROCESS_MEMORY_COUNTERS; +typedef PROCESS_MEMORY_COUNTERS *PPROCESS_MEMORY_COUNTERS; + +#endif // Z7_OLD_WIN_SDK + +#else // _WIN32 +#include <unistd.h> +#include <sys/ioctl.h> +#include <sys/time.h> +#include <sys/times.h> +#endif // _WIN32 -#if defined( _7ZIP_LARGE_PAGES) -#include "../../../../C/Alloc.h" -#endif +#include "../../../../C/CpuArch.h" #include "../../../Common/MyInitGuid.h" #include "../../../Common/CommandLineParser.h" #include "../../../Common/IntToString.h" #include "../../../Common/MyException.h" +#include "../../../Common/StdInStream.h" +#include "../../../Common/StdOutStream.h" #include "../../../Common/StringConvert.h" #include "../../../Common/StringToInt.h" #include "../../../Common/UTFConvert.h" #include "../../../Windows/ErrorMsg.h" - -#ifdef _WIN32 -#include "../../../Windows/MemoryLock.h" -#endif - #include "../../../Windows/TimeUtils.h" +#include "../../../Windows/FileDir.h" #include "../Common/ArchiveCommandLine.h" +#include "../Common/Bench.h" #include "../Common/ExitCode.h" #include "../Common/Extract.h" -#ifdef EXTERNAL_CODECS +#ifdef Z7_EXTERNAL_CODECS #include "../Common/LoadCodecs.h" #endif @@ -44,13 +70,12 @@ #include "BenchCon.h" #include "ConsoleClose.h" #include "ExtractCallbackConsole.h" +#include "HashCon.h" #include "List.h" #include "OpenCallbackConsole.h" #include "UpdateCallbackConsole.h" -#include "HashCon.h" - -#ifdef PROG_VARIANT_R +#ifdef Z7_PROG_VARIANT_R #include "../../../../C/7zVersion.h" #else #include "../../MyVersion.h" @@ -61,7 +86,9 @@ using namespace NFile; using namespace NCommandLineParser; #ifdef _WIN32 -HINSTANCE g_hInstance = 0; +extern +HINSTANCE g_hInstance; +HINSTANCE g_hInstance = NULL; #endif extern CStdOutStream *g_StdStream; @@ -73,34 +100,38 @@ extern const CCodecInfo *g_Codecs[]; extern unsigned g_NumHashers; extern const CHasherInfo *g_Hashers[]; -static const char *kCopyrightString = "\n7-Zip" -#ifndef EXTERNAL_CODECS -#ifdef PROG_VARIANT_R -" (r)" -#else -" (a)" -#endif +#ifdef Z7_EXTERNAL_CODECS +extern +const CExternalCodecs *g_ExternalCodecs_Ptr; +const CExternalCodecs *g_ExternalCodecs_Ptr; #endif -#ifdef MY_CPU_64BIT -" [64]" -#elif defined MY_CPU_32BIT -" [32]" +DECLARE_AND_SET_CLIENT_VERSION_VAR + +#if defined(Z7_PROG_VARIANT_Z) + #define PROG_POSTFIX "z" + #define PROG_POSTFIX_2 " (z)" +#elif defined(Z7_PROG_VARIANT_R) + #define PROG_POSTFIX "r" + #define PROG_POSTFIX_2 " (r)" +#elif !defined(Z7_EXTERNAL_CODECS) + #define PROG_POSTFIX "a" + #define PROG_POSTFIX_2 " (a)" +#else + #define PROG_POSTFIX "" + #define PROG_POSTFIX_2 "" #endif -" " MY_VERSION_COPYRIGHT_DATE "\n\n"; -static const char *kHelpString = +static const char * const kCopyrightString = "\n7-Zip" + PROG_POSTFIX_2 + " " MY_VERSION_CPU + " : " MY_COPYRIGHT_DATE "\n"; + +static const char * const kHelpString = "Usage: 7z" -#ifndef EXTERNAL_CODECS -#ifdef PROG_VARIANT_R - "r" -#else - "a" -#endif -#endif - " <command> [<switches>...] <archive_name> [<file_names>...]\n" - " [<@listfiles...>]\n" + PROG_POSTFIX + " <command> [<switches>...] <archive_name> [<file_names>...] [@listfile]\n" "\n" "<Commands>\n" " a : Add files to archive\n" @@ -116,7 +147,7 @@ static const char *kHelpString = " x : eXtract files with full paths\n" "\n" "<Switches>\n" - " -- : Stop switches parsing\n" + " -- : Stop switches and @listfile parsing\n" " -ai[r[-|0]]{@listfile|!wildcard} : Include archives\n" " -ax[r[-|0]]{@listfile|!wildcard} : eXclude archives\n" " -ao{a|s|t|u} : set Overwrite mode\n" @@ -128,13 +159,14 @@ static const char *kHelpString = " -i[r[-|0]]{@listfile|!wildcard} : Include filenames\n" " -m{Parameters} : set compression Method\n" " -mmt[N] : set number of CPU threads\n" + " -mx[N] : set compression level: -mx1 (fastest) ... -mx9 (ultra)\n" " -o{Directory} : set Output directory\n" - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO " -p{Password} : set Password\n" #endif - " -r[-|0] : Recurse subdirectories\n" + " -r[-|0] : Recurse subdirectories for name search\n" " -sa{a|e|s} : set Archive name mode\n" - " -scc{UTF-8|WIN|DOS} : set charset for for console input/output\n" + " -scc{UTF-8|WIN|DOS} : set charset for console input/output\n" " -scs{UTF-8|UTF-16LE|UTF-16BE|WIN|DOS|{id}} : set charset for list files\n" " -scrc[CRC32|CRC64|SHA1|SHA256|*] : set hash function for x, e, h commands\n" " -sdel : delete files after compression\n" @@ -150,8 +182,10 @@ static const char *kHelpString = " -so : write data to stdout\n" " -spd : disable wildcard matching for file names\n" " -spe : eliminate duplication of root folder for extract command\n" - " -spf : use fully qualified file paths\n" + " -spf[2] : use fully qualified file paths\n" " -ssc[-] : set sensitive case mode\n" + " -sse : stop archive creating, if it can't open some input file\n" + " -ssp : do not change Last Access Time of source files while archiving\n" " -ssw : compress shared files\n" " -stl : set archive timestamp from the most recently modified file\n" " -stm{HexMask} : set CPU thread affinity mask (hexadecimal number)\n" @@ -166,14 +200,15 @@ static const char *kHelpString = // --------------------------- // exception messages -static const char *kEverythingIsOk = "Everything is Ok"; -static const char *kUserErrorMessage = "Incorrect command line"; -static const char *kNoFormats = "7-Zip cannot find the code that works with archives."; -static const char *kUnsupportedArcTypeMessage = "Unsupported archive type"; -// static const char *kUnsupportedUpdateArcType = "Can't create archive for that type"; +static const char * const kEverythingIsOk = "Everything is Ok"; +static const char * const kUserErrorMessage = "Incorrect command line"; +static const char * const kNoFormats = "7-Zip cannot find the code that works with archives."; +static const char * const kUnsupportedArcTypeMessage = "Unsupported archive type"; +// static const char * const kUnsupportedUpdateArcType = "Can't create archive for that type"; -static CFSTR kDefaultSfxModule = FTEXT("7zCon.sfx"); +#define kDefaultSfxModule "7zCon.sfx" +Z7_ATTR_NORETURN static void ShowMessageAndThrowException(LPCSTR message, NExitCode::EEnum code) { if (g_ErrStream) @@ -181,15 +216,111 @@ static void ShowMessageAndThrowException(LPCSTR message, NExitCode::EEnum code) throw code; } -#ifndef _WIN32 -static void GetArguments(int numArgs, const char *args[], UStringVector &parts) + +#ifdef _WIN32 +#define ShowProgInfo(so) +#else +static void ShowProgInfo(CStdOutStream *so) { - parts.Clear(); - for (int i = 0; i < numArgs; i++) + if (!so) + return; + + *so + + /* + #ifdef __DATE__ + << " " << __DATE__ + #endif + #ifdef __TIME__ + << " " << __TIME__ + #endif + */ + + << " " << (unsigned)(sizeof(void *)) * 8 << "-bit" + + #ifdef __ILP32__ + << " ILP32" + #endif + + #ifdef __ARM_ARCH + << " arm_v:" << __ARM_ARCH + #ifdef __ARM_ARCH_ISA_THUMB + << " thumb:" << __ARM_ARCH_ISA_THUMB + #endif + #endif + ; + + + + #ifdef ENV_HAVE_LOCALE + *so << " locale=" << GetLocale(); + #endif + #ifndef _WIN32 { - UString s = MultiByteToUnicodeString(args[i]); - parts.Add(s); + const bool is_IsNativeUTF8 = IsNativeUTF8(); + if (!is_IsNativeUTF8) + *so << " UTF8=" << (is_IsNativeUTF8 ? "+" : "-"); } + if (!g_ForceToUTF8) + *so << " use-UTF8=" << (g_ForceToUTF8 ? "+" : "-"); + { + const unsigned wchar_t_size = (unsigned)sizeof(wchar_t); + if (wchar_t_size != 4) + *so << " wchar_t=" << wchar_t_size * 8 << "-bit"; + } + { + const unsigned off_t_size = (unsigned)sizeof(off_t); + if (off_t_size != 8) + *so << " Files=" << off_t_size * 8 << "-bit"; + } + #endif + + { + const UInt32 numCpus = NWindows::NSystem::GetNumberOfProcessors(); + *so << " Threads:" << numCpus; + const UInt64 openMAX= NWindows::NSystem::Get_File_OPEN_MAX(); + *so << " OPEN_MAX:" << openMAX; + { + FString temp; + NDir::MyGetTempPath(temp); + if (!temp.IsEqualTo(STRING_PATH_SEPARATOR "tmp" STRING_PATH_SEPARATOR)) + *so << " temp_path:" << temp; + } + } + + #ifdef Z7_7ZIP_ASM + *so << ", ASM"; + #endif + + /* + { + AString s; + GetCpuName(s); + s.Trim(); + *so << ", " << s; + } + + #ifdef __ARM_FEATURE_CRC32 + << " CRC32" + #endif + + + #if (defined MY_CPU_X86_OR_AMD64 || defined(MY_CPU_ARM_OR_ARM64)) + if (CPU_IsSupported_AES()) *so << ",AES"; + #endif + + #ifdef MY_CPU_ARM_OR_ARM64 + if (CPU_IsSupported_CRC32()) *so << ",CRC32"; + #if defined(_WIN32) + if (CPU_IsSupported_CRYPTO()) *so << ",CRYPTO"; + #else + if (CPU_IsSupported_SHA1()) *so << ",SHA1"; + if (CPU_IsSupported_SHA2()) *so << ",SHA2"; + #endif + #endif + */ + + *so << endl; } #endif @@ -199,14 +330,16 @@ static void ShowCopyrightAndHelp(CStdOutStream *so, bool needHelp) return; *so << kCopyrightString; // *so << "# CPUs: " << (UInt64)NWindows::NSystem::GetNumberOfProcessors() << endl; + ShowProgInfo(so); + *so << endl; if (needHelp) *so << kHelpString; } -static void PrintStringRight(CStdOutStream &so, const AString &s, unsigned size) +static void PrintStringRight(CStdOutStream &so, const char *s, unsigned size) { - unsigned len = s.Len(); + unsigned len = MyStringLen(s); for (unsigned i = len; i < size; i++) so << ' '; so << s; @@ -219,10 +352,21 @@ static void PrintUInt32(CStdOutStream &so, UInt32 val, unsigned size) PrintStringRight(so, s, size); } +#ifdef Z7_EXTERNAL_CODECS +static void PrintNumber(CStdOutStream &so, UInt32 val, unsigned numDigits) +{ + AString s; + s.Add_UInt32(val); + while (s.Len() < numDigits) + s.InsertAtFront('0'); + so << s; +} +#endif + static void PrintLibIndex(CStdOutStream &so, int libIndex) { if (libIndex >= 0) - PrintUInt32(so, libIndex, 2); + PrintUInt32(so, (UInt32)libIndex, 2); else so << " "; so << ' '; @@ -245,7 +389,8 @@ static void PrintWarningsPaths(const CErrorPathCodes &pc, CStdOutStream &so) { FOR_VECTOR(i, pc.Paths) { - so << pc.Paths[i] << " : "; + so.NormalizePrint_UString(fs2us(pc.Paths[i])); + so << " : "; so << NError::MyFormatMessage(pc.Codes[i]) << endl; } so << "----------------" << endl; @@ -279,7 +424,7 @@ static int WarningsCheck(HRESULT result, const CCallbackConsoleBase &callback, UString message; if (!errorInfo.Message.IsEmpty()) { - message.AddAscii(errorInfo.Message); + message += errorInfo.Message.Ptr(); message.Add_LF(); } { @@ -339,7 +484,6 @@ static void ThrowException_if_Error(HRESULT res) throw CSystemException(res); } - static void PrintNum(UInt64 val, unsigned numDigits, char c = ' ') { char temp[64]; @@ -351,6 +495,8 @@ static void PrintNum(UInt64 val, unsigned numDigits, char c = ' ') *g_StdStream << p; } +#ifdef _WIN32 + static void PrintTime(const char *s, UInt64 val, UInt64 total) { *g_StdStream << endl << s << " Time ="; @@ -384,11 +530,23 @@ static void PrintMemUsage(const char *s, UInt64 val) *g_StdStream << " " << s << " Memory ="; PrintNum(SHIFT_SIZE_VALUE(val, 20), 7); *g_StdStream << " MB"; + /* + *g_StdStream << " ="; + PrintNum(SHIFT_SIZE_VALUE(val, 10), 9); + *g_StdStream << " KB"; + */ + #ifdef Z7_LARGE_PAGES + AString lp; + Add_LargePages_String(lp); + if (!lp.IsEmpty()) + *g_StdStream << lp; + #endif } EXTERN_C_BEGIN typedef BOOL (WINAPI *Func_GetProcessMemoryInfo)(HANDLE Process, PPROCESS_MEMORY_COUNTERS ppsmemCounters, DWORD cb); +typedef BOOL (WINAPI *Func_QueryProcessCycleTime)(HANDLE Process, PULONG64 CycleTime); EXTERN_C_END #endif @@ -408,13 +566,15 @@ static void PrintStat() , &creationTimeFT, &exitTimeFT, &kernelTimeFT, &userTimeFT)) return; FILETIME curTimeFT; - NTime::GetCurUtcFileTime(curTimeFT); + NTime::GetCurUtc_FiTime(curTimeFT); #ifndef UNDER_CE PROCESS_MEMORY_COUNTERS m; memset(&m, 0, sizeof(m)); BOOL memDefined = FALSE; + BOOL cycleDefined = FALSE; + ULONG64 cycleTime = 0; { /* NT 4.0: GetProcessMemoryInfo() in Psapi.dll Win7: new function K32GetProcessMemoryInfo() in kernel32.dll @@ -424,18 +584,29 @@ static void PrintStat() The program with K32GetProcessMemoryInfo will not work on systems before Win7 // memDefined = GetProcessMemoryInfo(GetCurrentProcess(), &m, sizeof(m)); */ - - Func_GetProcessMemoryInfo my_GetProcessMemoryInfo = (Func_GetProcessMemoryInfo) - ::GetProcAddress(::GetModuleHandleW(L"kernel32.dll"), "K32GetProcessMemoryInfo"); + const HMODULE kern = ::GetModuleHandleW(L"kernel32.dll"); + Func_GetProcessMemoryInfo + my_GetProcessMemoryInfo = Z7_GET_PROC_ADDRESS( + Func_GetProcessMemoryInfo, kern, + "K32GetProcessMemoryInfo"); if (!my_GetProcessMemoryInfo) { - HMODULE lib = LoadLibraryW(L"Psapi.dll"); + const HMODULE lib = LoadLibraryW(L"Psapi.dll"); if (lib) - my_GetProcessMemoryInfo = (Func_GetProcessMemoryInfo)::GetProcAddress(lib, "GetProcessMemoryInfo"); + my_GetProcessMemoryInfo = Z7_GET_PROC_ADDRESS( + Func_GetProcessMemoryInfo, lib, + "GetProcessMemoryInfo"); } if (my_GetProcessMemoryInfo) memDefined = my_GetProcessMemoryInfo(GetCurrentProcess(), &m, sizeof(m)); // FreeLibrary(lib); + const + Func_QueryProcessCycleTime + my_QueryProcessCycleTime = Z7_GET_PROC_ADDRESS( + Func_QueryProcessCycleTime, kern, + "QueryProcessCycleTime"); + if (my_QueryProcessCycleTime) + cycleDefined = my_QueryProcessCycleTime(GetCurrentProcess(), &cycleTime); } #endif @@ -448,9 +619,33 @@ static void PrintStat() UInt64 totalTime = curTime - creationTime; PrintTime("Kernel ", kernelTime, totalTime); + + const UInt64 processTime = kernelTime + userTime; + + #ifndef UNDER_CE + if (cycleDefined) + { + *g_StdStream << " Cnt:"; + PrintNum(cycleTime / 1000000, 15); + *g_StdStream << " MCycles"; + } + #endif + PrintTime("User ", userTime, totalTime); + + #ifndef UNDER_CE + if (cycleDefined) + { + *g_StdStream << " Freq (cnt/ptime):"; + UInt64 us = processTime / 10; + if (us == 0) + us = 1; + PrintNum(cycleTime / us, 6); + *g_StdStream << " MHz"; + } + #endif - PrintTime("Process", kernelTime + userTime, totalTime); + PrintTime("Process", processTime, totalTime); #ifndef UNDER_CE if (memDefined) PrintMemUsage("Virtual ", m.PeakPagefileUsage); #endif @@ -459,10 +654,97 @@ static void PrintStat() #ifndef UNDER_CE if (memDefined) PrintMemUsage("Physical", m.PeakWorkingSetSize); #endif + *g_StdStream << endl; +} + + +#else // ! _WIN32 + +static UInt64 Get_timeofday_us() +{ + struct timeval now; + if (gettimeofday(&now, NULL) == 0) + return (UInt64)now.tv_sec * 1000000 + (UInt64)now.tv_usec; + return 0; +} + +static void PrintTime(const char *s, UInt64 val, UInt64 total_us, UInt64 kFreq) +{ + *g_StdStream << endl << s << " Time ="; + + { + UInt64 sec, ms; + + if (kFreq == 0) + { + sec = val / 1000000; + ms = val % 1000000 / 1000; + } + else + { + sec = val / kFreq; + ms = (UInt32)((val - (sec * kFreq)) * 1000 / kFreq); + } + + PrintNum(sec, 6); + *g_StdStream << '.'; + PrintNum(ms, 3, '0'); + } + if (total_us == 0) + return; + + UInt64 percent = 0; + if (kFreq == 0) + percent = val * 100 / total_us; + else + { + const UInt64 kMaxVal = (UInt64)(Int64)-1; + UInt32 m = 100000000; + for (;;) + { + if (m == 0 || kFreq == 0) + break; + if (kMaxVal / m > val && + kMaxVal / kFreq > total_us) + break; + if (val > m) + val >>= 1; + else + m >>= 1; + if (kFreq > total_us) + kFreq >>= 1; + else + total_us >>= 1; + } + const UInt64 total = kFreq * total_us; + if (total != 0) + percent = val * m / total; + } + *g_StdStream << " ="; + PrintNum(percent, 5); + *g_StdStream << '%'; +} + +static void PrintStat(const UInt64 startTime) +{ + tms t; + /* clock_t res = */ times(&t); + const UInt64 totalTime = Get_timeofday_us() - startTime; + const UInt64 kFreq = (UInt64)sysconf(_SC_CLK_TCK); + PrintTime("Kernel ", (UInt64)t.tms_stime, totalTime, kFreq); + PrintTime("User ", (UInt64)t.tms_utime, totalTime, kFreq); + PrintTime("Process", (UInt64)t.tms_utime + (UInt64)t.tms_stime, totalTime, kFreq); + PrintTime("Global ", totalTime, totalTime, 0); *g_StdStream << endl; } +#endif // ! _WIN32 + + + + + static void PrintHexId(CStdOutStream &so, UInt64 id) { char s[32]; @@ -470,38 +752,97 @@ static void PrintHexId(CStdOutStream &so, UInt64 id) PrintStringRight(so, s, 8); } +#ifndef _WIN32 +void Set_ModuleDirPrefix_From_ProgArg0(const char *s); +#endif + +int Main2( + #ifndef _WIN32 + int numArgs, char *args[] + #endif +); int Main2( #ifndef _WIN32 int numArgs, char *args[] #endif ) { + #if defined(MY_CPU_SIZEOF_POINTER) + { unsigned k = sizeof(void *); if (k != MY_CPU_SIZEOF_POINTER) throw "incorrect MY_CPU_PTR_SIZE"; } + #endif + #if defined(_WIN32) && !defined(UNDER_CE) SetFileApisToOEM(); #endif + #ifdef ENV_HAVE_LOCALE + // printf("\nBefore SetLocale() : %s\n", IsNativeUtf8() ? "NATIVE UTF-8" : "IS NOT NATIVE UTF-8"); + MY_SetLocale(); + // printf("\nAfter SetLocale() : %s\n", IsNativeUtf8() ? "NATIVE UTF-8" : "IS NOT NATIVE UTF-8"); + #endif + + #ifndef _WIN32 + const UInt64 startTime = Get_timeofday_us(); + #endif + + /* + { + g_StdOut << "DWORD:" << (unsigned)sizeof(DWORD); + g_StdOut << " LONG:" << (unsigned)sizeof(LONG); + g_StdOut << " long:" << (unsigned)sizeof(long); + #ifdef _WIN64 + // g_StdOut << " long long:" << (unsigned)sizeof(long long); + #endif + g_StdOut << " int:" << (unsigned)sizeof(int); + g_StdOut << " void*:" << (unsigned)sizeof(void *); + g_StdOut << endl; + } + */ + UStringVector commandStrings; #ifdef _WIN32 NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings); #else - GetArguments(numArgs, args, commandStrings); + { + if (numArgs > 0) + Set_ModuleDirPrefix_From_ProgArg0(args[0]); + + for (int i = 0; i < numArgs; i++) + { + AString a (args[i]); + /* + printf("\n%d %s :", i, a.Ptr()); + for (unsigned k = 0; k < a.Len(); k++) + printf(" %2x", (unsigned)(Byte)a[k]); + */ + const UString s = MultiByteToUnicodeString(a); + commandStrings.Add(s); + } + // printf("\n"); + } + #endif - if (commandStrings.Size() == 1) + #ifndef UNDER_CE + if (commandStrings.Size() > 0) + commandStrings.Delete(0); + #endif + + if (commandStrings.Size() == 0) { ShowCopyrightAndHelp(g_StdStream, true); return 0; } - commandStrings.Delete(0); - CArcCmdLineOptions options; CArcCmdLineParser parser; parser.Parse1(commandStrings, options); + g_StdOut.IsTerminalMode = options.IsStdOutTerminal; + g_StdErr.IsTerminalMode = options.IsStdErrTerminal; if (options.Number_for_Out != k_OutStream_stdout) g_StdStream = (options.Number_for_Out == k_OutStream_stderr ? &g_StdErr : NULL); @@ -511,7 +852,7 @@ int Main2( CStdOutStream *percentsStream = NULL; if (options.Number_for_Percents != k_OutStream_disabled) - percentsStream = (options.Number_for_Percents == k_OutStream_stderr) ? &g_StdErr : &g_StdOut;; + percentsStream = (options.Number_for_Percents == k_OutStream_stderr) ? &g_StdErr : &g_StdOut; if (options.HelpMode) { @@ -519,25 +860,54 @@ int Main2( return 0; } - #if defined(_WIN32) && !defined(UNDER_CE) - NSecurity::EnablePrivilege_SymLink(); - #endif - - #ifdef _7ZIP_LARGE_PAGES - if (options.LargePages) - { - SetLargePageSize(); - #if defined(_WIN32) && !defined(UNDER_CE) - NSecurity::EnablePrivilege_LockMemory(); - #endif - } - #endif - if (options.EnableHeaders) + { ShowCopyrightAndHelp(g_StdStream, false); + if (!parser.Parse1Log.IsEmpty()) + *g_StdStream << parser.Parse1Log; + } parser.Parse2(options); + { + int cp = options.ConsoleCodePage; + + int stdout_cp = cp; + int stderr_cp = cp; + int stdin_cp = cp; + + /* + // these cases are complicated. + // maybe we must use CRT functions instead of console WIN32. + // different Windows/CRT versions also can work different ways. + // so the following code was not enabled: + if (cp == -1) + { + // we set CodePage only if stream is attached to terminal + // maybe we should set CodePage even if is not terminal? + #ifdef _WIN32 + { + UINT ccp = GetConsoleOutputCP(); + if (ccp != 0) + { + if (options.IsStdOutTerminal) stdout_cp = ccp; + if (options.IsStdErrTerminal) stderr_cp = ccp; + } + } + if (options.IsInTerminal) + { + UINT ccp = GetConsoleCP(); + if (ccp != 0) stdin_cp = ccp; + } + #endif + } + */ + + if (stdout_cp != -1) g_StdOut.CodePage = stdout_cp; + if (stderr_cp != -1) g_StdErr.CodePage = stderr_cp; + if (stdin_cp != -1) g_StdIn.CodePage = stdin_cp; + } + unsigned percentsNameLevel = 1; if (options.LogLevel == 0 || options.Number_for_Percents != options.Number_for_Out) percentsNameLevel = 2; @@ -551,13 +921,13 @@ int Main2( #if !defined(UNDER_CE) CONSOLE_SCREEN_BUFFER_INFO consoleInfo; if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &consoleInfo)) - consoleWidth = consoleInfo.dwSize.X; + consoleWidth = (unsigned)(unsigned short)consoleInfo.dwSize.X; #endif #else struct winsize w; - if (ioctl(0, TIOCGWINSZ, &w) == ) + if (ioctl(0, TIOCGWINSZ, &w) == 0) consoleWidth = w.ws_col; #endif @@ -565,32 +935,48 @@ int Main2( CREATE_CODECS_OBJECT - codecs->CaseSensitiveChange = options.CaseSensitiveChange; + codecs->CaseSensitive_Change = options.CaseSensitive_Change; codecs->CaseSensitive = options.CaseSensitive; ThrowException_if_Error(codecs->Load()); + Codecs_AddHashArcHandler(codecs); - bool isExtractGroupCommand = options.Command.IsFromExtractGroup(); + #ifdef Z7_EXTERNAL_CODECS + { + g_ExternalCodecs_Ptr = &_externalCodecs; + UString s; + codecs->GetCodecsErrorMessage(s); + if (!s.IsEmpty()) + { + CStdOutStream &so = (g_StdStream ? *g_StdStream : g_StdOut); + so << endl << s << endl; + } + } + #endif + + const bool isExtractGroupCommand = options.Command.IsFromExtractGroup(); if (codecs->Formats.Size() == 0 && (isExtractGroupCommand || options.Command.CommandType == NCommandType::kList || options.Command.IsFromUpdateGroup())) { - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS if (!codecs->MainDll_ErrorPath.IsEmpty()) { - UString s = L"Can't load module "; + UString s ("Can't load module: "); s += fs2us(codecs->MainDll_ErrorPath); throw s; } #endif - throw kNoFormats; } CObjectVector<COpenType> types; if (!ParseOpenTypes(*codecs, options.ArcType, types)) + { throw kUnsupportedArcTypeMessage; + } + CIntVector excludedFormats; FOR_VECTOR (k, options.ExcludedArcTypes) @@ -599,16 +985,19 @@ int Main2( if (!codecs->FindFormatForArchiveType(options.ExcludedArcTypes[k], tempIndices) || tempIndices.Size() != 1) throw kUnsupportedArcTypeMessage; + + + excludedFormats.AddToUniqueSorted(tempIndices[0]); // excludedFormats.Sort(); } - - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS if (isExtractGroupCommand + || options.Command.IsFromUpdateGroup() || options.Command.CommandType == NCommandType::kHash || options.Command.CommandType == NCommandType::kBenchmark) - ThrowException_if_Error(__externalCodecs.Load()); + ThrowException_if_Error(_externalCodecs.Load()); #endif int retCode = NExitCode::kSuccess; @@ -628,38 +1017,54 @@ int Main2( CStdOutStream &so = (g_StdStream ? *g_StdStream : g_StdOut); unsigned i; - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS so << endl << "Libs:" << endl; for (i = 0; i < codecs->Libs.Size(); i++) { - PrintLibIndex(so, i); - so << ' ' << codecs->Libs[i].Path << endl; + PrintLibIndex(so, (int)i); + const CCodecLib &lib = codecs->Libs[i]; + // if (lib.Version != 0) + so << ": " << (lib.Version >> 16) << "."; + PrintNumber(so, lib.Version & 0xffff, 2); + so << " : " << lib.Path << endl; } #endif so << endl << "Formats:" << endl; - const char *kArcFlags = "KSNFMGOPBELH"; + const char * const kArcFlags = "KSNFMGOPBELHXCc+a+m+r+"; + const char * const kArcTimeFlags = "wudn"; const unsigned kNumArcFlags = (unsigned)strlen(kArcFlags); - + const unsigned kNumArcTimeFlags = (unsigned)strlen(kArcTimeFlags); + for (i = 0; i < codecs->Formats.Size(); i++) { const CArcInfoEx &arc = codecs->Formats[i]; - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS PrintLibIndex(so, arc.LibIndex); #else - so << " "; + so << " "; #endif so << (char)(arc.UpdateEnabled ? 'C' : ' '); - for (unsigned b = 0; b < kNumArcFlags; b++) { - so << (char) - ((arc.Flags & ((UInt32)1 << b)) != 0 ? kArcFlags[b] : ' '); + unsigned b; + for (b = 0; b < kNumArcFlags; b++) + so << (char)((arc.Flags & ((UInt32)1 << b)) != 0 ? kArcFlags[b] : '.'); + so << ' '; } - + + if (arc.TimeFlags != 0) + { + unsigned b; + for (b = 0; b < kNumArcTimeFlags; b++) + so << (char)((arc.TimeFlags & ((UInt32)1 << b)) != 0 ? kArcTimeFlags[b] : '.'); + so << arc.Get_DefaultTimePrec(); + so << ' '; + } + so << ' '; PrintString(so, arc.Name, 8); so << ' '; @@ -673,9 +1078,9 @@ int Main2( s += ext.Ext; if (!ext.AddExt.IsEmpty()) { - s += L" ("; + s += " ("; s += ext.AddExt; - s += L')'; + s += ')'; } } @@ -685,6 +1090,8 @@ int Main2( if (arc.SignatureOffset != 0) so << "offset=" << arc.SignatureOffset << ' '; + // so << "numSignatures = " << arc.Signatures.Size() << " "; + FOR_VECTOR(si, arc.Signatures) { if (si != 0) @@ -726,6 +1133,7 @@ int Main2( so << (char)(cod.CreateEncoder ? 'E' : ' '); so << (char)(cod.CreateDecoder ? 'D' : ' '); + so << (char)(cod.IsFilter ? 'F' : ' '); so << ' '; PrintHexId(so, cod.Id); @@ -733,10 +1141,10 @@ int Main2( } - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS UInt32 numMethods; - if (codecs->GetNumMethods(&numMethods) == S_OK) + if (_externalCodecs.GetCodecs->GetNumMethods(&numMethods) == S_OK) for (UInt32 j = 0; j < numMethods; j++) { PrintLibIndex(so, codecs->GetCodec_LibIndex(j)); @@ -749,6 +1157,12 @@ int Main2( so << (char)(codecs->GetCodec_EncoderIsAssigned(j) ? 'E' : ' '); so << (char)(codecs->GetCodec_DecoderIsAssigned(j) ? 'D' : ' '); + { + bool isFilter_Assigned; + const bool isFilter = codecs->GetCodec_IsFilter(j, isFilter_Assigned); + so << (char)(isFilter ? 'F' : isFilter_Assigned ? ' ' : '*'); + } + so << ' '; UInt64 id; @@ -774,9 +1188,9 @@ int Main2( so << ' ' << codec.Name << endl; } - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS - numMethods = codecs->GetNumHashers(); + numMethods = _externalCodecs.GetHashers->GetNumHashers(); for (UInt32 j = 0; j < numMethods; j++) { PrintLibIndex(so, codecs->GetHasherLibIndex(j)); @@ -796,6 +1210,7 @@ int Main2( options.Properties, options.NumIterations, (FILE *)so); if (hresultMain == S_FALSE) { + so << endl; if (g_ErrStream) *g_ErrStream << "\nDecoding ERROR\n"; retCode = NExitCode::kFatalError; @@ -855,13 +1270,13 @@ int Main2( } } - if (hresultMain == S_OK) + if (hresultMain == S_OK) { if (isExtractGroupCommand) { CExtractCallbackConsole *ecs = new CExtractCallbackConsole; CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs; - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO ecs->PasswordIsDefined = options.PasswordEnabled; ecs->Password = options.Password; #endif @@ -879,7 +1294,7 @@ int Main2( COpenCallbackConsole openCallback; openCallback.Init(g_StdStream, g_ErrStream); - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO openCallback.PasswordIsDefined = options.PasswordEnabled; openCallback.Password = options.Password; #endif @@ -893,7 +1308,7 @@ int Main2( eo.YesToAll = options.YesToAll; eo.TestMode = options.Command.IsTestCommand(); - #ifndef _SFX + #ifndef Z7_SFX eo.Properties = options.Properties; #endif @@ -906,17 +1321,20 @@ int Main2( { hashCalc = &hb; ThrowException_if_Error(hb.SetMethods(EXTERNAL_CODECS_VARS_L options.HashMethods)); - hb.Init(); + // hb.Init(); } hresultMain = Extract( + // EXTERNAL_CODECS_VARS_L codecs, types, excludedFormats, ArchivePathsSorted, ArchivePathsFullSorted, options.Censor.Pairs.Front().Head, - eo, ecs, ecs, hashCalc, errorMessage, stat); + eo, + ecs, ecs, ecs, + hashCalc, errorMessage, stat); ecs->ClosePercents(); @@ -984,7 +1402,7 @@ int Main2( if (isError) retCode = NExitCode::kFatalError; - if (so) + if (so) { if (ecs->NumArcsWithError != 0 || ecs->NumFileErrors != 0) { // if (ecs->NumArchives > 1) @@ -1015,15 +1433,21 @@ int Main2( PrintHashStat(*so, hb); } } + } // if (so) } - else + else // if_(!isExtractGroupCommand) { UInt64 numErrors = 0; UInt64 numWarnings = 0; // options.ExtractNtOptions.StoreAltStreams = true, if -sns[-] is not definmed + CListOptions lo; + lo.ExcludeDirItems = options.Censor.ExcludeDirItems; + lo.ExcludeFileItems = options.Censor.ExcludeFileItems; + hresultMain = ListArchives( + lo, codecs, types, excludedFormats, @@ -1035,7 +1459,7 @@ int Main2( options.Censor.Pairs.Front().Head, options.EnableHeaders, options.TechMode, - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO options.PasswordEnabled, options.Password, #endif @@ -1052,7 +1476,8 @@ int Main2( g_StdOut << endl << "Errors: " << numErrors << endl; retCode = NExitCode::kFatalError; } - } + } // if_(isExtractGroupCommand) + } // if_(hresultMain == S_OK) } else if (options.Command.IsFromUpdateGroup()) { @@ -1063,7 +1488,7 @@ int Main2( COpenCallbackConsole openCallback; openCallback.Init(g_StdStream, g_ErrStream, percentsStream); - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO bool passwordIsDefined = (options.PasswordEnabled && !options.Password.IsEmpty()); openCallback.PasswordIsDefined = passwordIsDefined; @@ -1077,7 +1502,7 @@ int Main2( if (percentsStream) callback.SetWindowWidth(consoleWidth); - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO callback.PasswordIsDefined = passwordIsDefined; callback.AskPassword = (options.PasswordEnabled && options.Password.IsEmpty()); callback.Password = options.Password; @@ -1122,6 +1547,7 @@ int Main2( callback.Init(g_StdStream, g_ErrStream, percentsStream); callback.PrintHeaders = options.EnableHeaders; + callback.PrintFields = options.ListFields; AString errorInfoString; hresultMain = HashCalc(EXTERNAL_CODECS_VARS_L @@ -1138,7 +1564,11 @@ int Main2( ShowMessageAndThrowException(kUserErrorMessage, NExitCode::kUserError); if (options.ShowTime && g_StdStream) - PrintStat(); + PrintStat( + #ifndef _WIN32 + startTime + #endif + ); ThrowException_if_Error(hresultMain); diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/MainAr.cpp b/3rdparty/lzma/CPP/7zip/UI/Console/MainAr.cpp index d30a96e4be2..80f84f5e657 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/MainAr.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Console/MainAr.cpp @@ -2,6 +2,11 @@ #include "StdAfx.h" +#ifdef _WIN32 +#include "../../../../C/DllSecur.h" +#endif +#include "../../../../C/CpuArch.h" + #include "../../../Common/MyException.h" #include "../../../Common/StdOutStream.h" @@ -15,7 +20,11 @@ using namespace NWindows; +extern +CStdOutStream *g_StdStream; CStdOutStream *g_StdStream = NULL; +extern +CStdOutStream *g_ErrStream; CStdOutStream *g_ErrStream = NULL; extern int Main2( @@ -24,12 +33,12 @@ extern int Main2( #endif ); -static const char *kException_CmdLine_Error_Message = "Command Line Error:"; -static const char *kExceptionErrorMessage = "ERROR:"; -static const char *kUserBreakMessage = "Break signaled"; -static const char *kMemoryExceptionMessage = "ERROR: Can't allocate required memory!"; -static const char *kUnknownExceptionMessage = "Unknown Error"; -static const char *kInternalExceptionMessage = "\n\nInternal Error #"; +static const char * const kException_CmdLine_Error_Message = "Command Line Error:"; +static const char * const kExceptionErrorMessage = "ERROR:"; +static const char * const kUserBreakMessage = "Break signaled"; +static const char * const kMemoryExceptionMessage = "ERROR: Can't allocate required memory!"; +static const char * const kUnknownExceptionMessage = "Unknown Error"; +static const char * const kInternalExceptionMessage = "\n\nInternal Error #"; static void FlushStreams() { @@ -44,9 +53,48 @@ static void PrintError(const char *message) *g_ErrStream << "\n\n" << message << endl; } +#if defined(_WIN32) && defined(_UNICODE) && !defined(_WIN64) && !defined(UNDER_CE) #define NT_CHECK_FAIL_ACTION *g_StdStream << "Unsupported Windows version"; return NExitCode::kFatalError; +#endif + +static inline bool CheckIsa() +{ + // __try + { + #if defined(__AVX2__) + if (!CPU_IsSupported_AVX2()) + return false; + #elif defined(__AVX__) + if (!CPU_IsSupported_AVX()) + return false; + #elif defined(__SSE2__) && !defined(MY_CPU_AMD64) || defined(_M_IX86_FP) && (_M_IX86_FP >= 2) + if (!CPU_IsSupported_SSE2()) + return false; + #elif defined(__SSE__) && !defined(MY_CPU_AMD64) || defined(_M_IX86_FP) && (_M_IX86_FP >= 1) + if (!CPU_IsSupported_SSE() || + !CPU_IsSupported_CMOV()) + return false; + #endif + /* + __asm + { + _emit 0fH + _emit 038H + _emit 0cbH + _emit (0c0H + 0 * 8 + 0) + } + */ + return true; + } + /* + __except (EXCEPTION_EXECUTE_HANDLER) + { + return false; + } + */ +} -int MY_CDECL main +int Z7_CDECL main ( #ifndef _WIN32 int numArgs, char *args[] @@ -56,6 +104,14 @@ int MY_CDECL main g_ErrStream = &g_StdErr; g_StdStream = &g_StdOut; + // #if (defined(_MSC_VER) && defined(_M_IX86)) + if (!CheckIsa()) + { + PrintError("ERROR: processor doesn't support required ISA extension"); + return NExitCode::kFatalError; + } + // #endif + NT_CHECK NConsoleClose::CCtrlHandlerSetter ctrlHandlerSetter; @@ -63,6 +119,10 @@ int MY_CDECL main try { + #ifdef _WIN32 + My_SetDefaultDllDirectories(); + #endif + res = Main2( #ifndef _WIN32 numArgs, args @@ -79,7 +139,7 @@ int MY_CDECL main PrintError(kUserBreakMessage); return (NExitCode::kUserBreak); } - catch(const CArcCmdLineException &e) + catch(const CMessagePathException &e) { PrintError(kException_CmdLine_Error_Message); if (g_ErrStream) @@ -105,7 +165,7 @@ int MY_CDECL main } return (NExitCode::kFatalError); } - catch(NExitCode::EEnum &exitCode) + catch(NExitCode::EEnum exitCode) { FlushStreams(); if (g_ErrStream) diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/OpenCallbackConsole.cpp b/3rdparty/lzma/CPP/7zip/UI/Console/OpenCallbackConsole.cpp index 9d25a729ca0..1e7adf5d427 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/OpenCallbackConsole.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Console/OpenCallbackConsole.cpp @@ -32,13 +32,17 @@ HRESULT COpenCallbackConsole::Open_SetTotal(const UInt64 *files, const UInt64 *b if (bytes) { - _totalBytesDefined = true; - // _totalBytes = *bytes; + // _totalBytesDefined = true; + _totalBytes = *bytes; if (!files) _percent.Total = *bytes; } else - _totalBytesDefined = false; + { + // _totalBytesDefined = false; + if (!files) + _percent.Total = _totalBytes; + } } return CheckBreak2(); @@ -73,17 +77,17 @@ HRESULT COpenCallbackConsole::Open_Finished() } -#ifndef _NO_CRYPTO +#ifndef Z7_NO_CRYPTO HRESULT COpenCallbackConsole::Open_CryptoGetTextPassword(BSTR *password) { *password = NULL; - RINOK(CheckBreak2()); + RINOK(CheckBreak2()) if (!PasswordIsDefined) { ClosePercents(); - Password = GetPassword(_so); + RINOK(GetPassword_HRESULT(_so, Password)) PasswordIsDefined = true; } return StringToBstr(Password, password); diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/OpenCallbackConsole.h b/3rdparty/lzma/CPP/7zip/UI/Console/OpenCallbackConsole.h index 0dd4e1d1c82..c5b4b45fc0e 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/OpenCallbackConsole.h +++ b/3rdparty/lzma/CPP/7zip/UI/Console/OpenCallbackConsole.h @@ -1,7 +1,7 @@ // OpenCallbackConsole.h -#ifndef __OPEN_CALLBACK_CONSOLE_H -#define __OPEN_CALLBACK_CONSOLE_H +#ifndef ZIP7_INC_OPEN_CALLBACK_CONSOLE_H +#define ZIP7_INC_OPEN_CALLBACK_CONSOLE_H #include "../../../Common/StdOutStream.h" @@ -17,10 +17,10 @@ protected: CStdOutStream *_so; CStdOutStream *_se; - bool _totalFilesDefined; - bool _totalBytesDefined; // UInt64 _totalFiles; - // UInt64 _totalBytes; + UInt64 _totalBytes; + bool _totalFilesDefined; + // bool _totalBytesDefined; bool NeedPercents() const { return _percent._so != NULL; } @@ -35,16 +35,19 @@ public: } COpenCallbackConsole(): + _totalBytes(0), _totalFilesDefined(false), - _totalBytesDefined(false), + // _totalBytesDefined(false), MultiArcMode(false) - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO , PasswordIsDefined(false) // , PasswordWasAsked(false) #endif {} + + virtual ~COpenCallbackConsole() {} void Init(CStdOutStream *outStream, CStdOutStream *errorStream, CStdOutStream *percentStream) { @@ -53,9 +56,9 @@ public: _percent._so = percentStream; } - INTERFACE_IOpenCallbackUI(;) + Z7_IFACE_IMP(IOpenCallbackUI) - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO bool PasswordIsDefined; // bool PasswordWasAsked; UString Password; diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/PercentPrinter.cpp b/3rdparty/lzma/CPP/7zip/UI/Console/PercentPrinter.cpp index e3e8d599811..9d392abe559 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/PercentPrinter.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Console/PercentPrinter.cpp @@ -63,7 +63,8 @@ void CPercentPrinter::GetPercents() { char c = '%'; UInt64 val = 0; - if (Total == (UInt64)(Int64)-1) + if (Total == (UInt64)(Int64)-1 || + (Total == 0 && Completed != 0)) { val = Completed >> 20; c = 'M'; @@ -78,7 +79,7 @@ void CPercentPrinter::GetPercents() while (size < kPercentsSize) { - _s += ' '; + _s.Add_Space(); size++; } @@ -124,8 +125,8 @@ void CPercentPrinter::Print() char s[32]; ConvertUInt64ToString(Files, s); // unsigned size = (unsigned)strlen(s); - // for (; size < 3; size++) _s += ' '; - _s += ' '; + // for (; size < 3; size++) _s.Add_Space(); + _s.Add_Space(); _s += s; // _s += "f"; } @@ -133,16 +134,17 @@ void CPercentPrinter::Print() if (!Command.IsEmpty()) { - _s += ' '; + _s.Add_Space(); _s += Command; } if (!FileName.IsEmpty() && _s.Len() < MaxLen) { - _s += ' '; + _s.Add_Space(); - StdOut_Convert_UString_to_AString(FileName, _temp); - _temp.Replace('\n', ' '); + _tempU = FileName; + _so->Normalize_UString(_tempU); + _so->Convert_UString_to_AString(_tempU, _temp); if (_s.Len() + _temp.Len() > MaxLen) { unsigned len = FileName.Len(); @@ -153,9 +155,10 @@ void CPercentPrinter::Print() delta = 1; len -= delta; _tempU = FileName; - _tempU.Delete(len / 2, FileName.Len() - len); + _tempU.Delete(len / 2, _tempU.Len() - len); _tempU.Insert(len / 2, L" . "); - StdOut_Convert_UString_to_AString(_tempU, _temp); + _so->Normalize_UString(_tempU); + _so->Convert_UString_to_AString(_tempU, _temp); if (_s.Len() + _temp.Len() <= MaxLen) break; } diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/PercentPrinter.h b/3rdparty/lzma/CPP/7zip/UI/Console/PercentPrinter.h index 95290b37e9c..4debb3b60ee 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/PercentPrinter.h +++ b/3rdparty/lzma/CPP/7zip/UI/Console/PercentPrinter.h @@ -1,7 +1,7 @@ // PercentPrinter.h -#ifndef __PERCENT_PRINTER_H -#define __PERCENT_PRINTER_H +#ifndef ZIP7_INC_PERCENT_PRINTER_H +#define ZIP7_INC_PERCENT_PRINTER_H #include "../../../Common/StdOutStream.h" diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/StdAfx.h b/3rdparty/lzma/CPP/7zip/UI/Console/StdAfx.h index 2854ff3e935..035267ccd02 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/StdAfx.h +++ b/3rdparty/lzma/CPP/7zip/UI/Console/StdAfx.h @@ -1,8 +1,11 @@ // StdAfx.h -#ifndef __STDAFX_H -#define __STDAFX_H +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif #include "../../../Common/Common.h" #endif diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp b/3rdparty/lzma/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp index f4f2d10210d..85496f5b16c 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp @@ -5,33 +5,36 @@ #include "../../../Common/IntToString.h" #include "../../../Windows/ErrorMsg.h" +#include "../../../Windows/FileName.h" -#ifndef _7ZIP_ST +#ifndef Z7_ST #include "../../../Windows/Synchronization.h" #endif +// #include "../Common/PropIDUtils.h" + #include "ConsoleClose.h" #include "UserInputUtils.h" #include "UpdateCallbackConsole.h" using namespace NWindows; -#ifndef _7ZIP_ST +#ifndef Z7_ST static NSynchronization::CCriticalSection g_CriticalSection; #define MT_LOCK NSynchronization::CCriticalSectionLock lock(g_CriticalSection); #else #define MT_LOCK #endif -static const wchar_t *kEmptyFileAlias = L"[Content]"; +static const wchar_t * const kEmptyFileAlias = L"[Content]"; -static const char *kOpenArchiveMessage = "Open archive: "; -static const char *kCreatingArchiveMessage = "Creating archive: "; -static const char *kUpdatingArchiveMessage = "Updating archive: "; -static const char *kScanningMessage = "Scanning the drive:"; +static const char * const kOpenArchiveMessage = "Open archive: "; +static const char * const kCreatingArchiveMessage = "Creating archive: "; +static const char * const kUpdatingArchiveMessage = "Updating archive: "; +static const char * const kScanningMessage = "Scanning the drive:"; -static const char *kError = "ERROR: "; -static const char *kWarning = "WARNING: "; +static const char * const kError = "ERROR: "; +static const char * const kWarning = "WARNING: "; static HRESULT CheckBreak2() { @@ -133,7 +136,7 @@ HRESULT CUpdateCallbackConsole::OpenResult( { if (_so) { - RINOK(Print_OpenArchive_Props(*_so, codecs, arcLink)); + RINOK(Print_OpenArchive_Props(*_so, codecs, arcLink)) *_so << endl; } } @@ -143,9 +146,11 @@ HRESULT CUpdateCallbackConsole::OpenResult( _so->Flush(); if (_se) { - *_se << kError << name << endl; + *_se << kError; + _se->NormalizePrint_wstr(name); + *_se << endl; HRESULT res = Print_OpenArchive_Error(*_se, codecs, arcLink); - RINOK(res); + RINOK(res) _se->Flush(); } } @@ -185,11 +190,29 @@ void CCallbackConsoleBase::CommonError(const FString &path, DWORD systemError, b *_se << endl << (isWarning ? kWarning : kError) << NError::MyFormatMessage(systemError) - << endl << fs2us(path) << endl << endl; + << endl; + _se->NormalizePrint_UString(fs2us(path)); + *_se << endl << endl; _se->Flush(); } } +/* +void CCallbackConsoleBase::CommonError(const char *message) +{ + ClosePercents2(); + + if (_se) + { + if (_so) + _so->Flush(); + + *_se << endl << kError << message << endl; + _se->Flush(); + } +} +*/ + HRESULT CCallbackConsoleBase::ScanError_Base(const FString &path, DWORD systemError) { @@ -205,6 +228,7 @@ HRESULT CCallbackConsoleBase::OpenFileError_Base(const FString &path, DWORD syst { MT_LOCK FailedFiles.AddError(path, systemError); + NumNonOpenFiles++; /* if (systemError == ERROR_SHARING_VIOLATION) { @@ -241,6 +265,7 @@ static void PrintPropPair(AString &s, const char *name, UInt64 val) void PrintSize_bytes_Smart(AString &s, UInt64 val); void Print_DirItemsStat(AString &s, const CDirItemsStat &st); +void Print_DirItemsStat2(AString &s, const CDirItemsStat2 &st); HRESULT CUpdateCallbackConsole::FinishScanning(const CDirItemsStat &st) { @@ -259,7 +284,7 @@ HRESULT CUpdateCallbackConsole::FinishScanning(const CDirItemsStat &st) return S_OK; } -static const char *k_StdOut_ArcName = "StdOut"; +static const char * const k_StdOut_ArcName = "StdOut"; HRESULT CUpdateCallbackConsole::StartOpenArchive(const wchar_t *name) { @@ -277,11 +302,17 @@ HRESULT CUpdateCallbackConsole::StartOpenArchive(const wchar_t *name) HRESULT CUpdateCallbackConsole::StartArchive(const wchar_t *name, bool updating) { + if (NeedPercents()) + _percent.ClosePrint(true); + + _percent.ClearCurState(); + NumNonOpenFiles = 0; + if (_so) { *_so << (updating ? kUpdatingArchiveMessage : kCreatingArchiveMessage); - if (name != 0) - *_so << name; + if (name) + _so->NormalizePrint_wstr(name); else *_so << k_StdOut_ArcName; *_so << endl << endl; @@ -297,11 +328,17 @@ HRESULT CUpdateCallbackConsole::FinishArchive(const CFinishArchiveStat &st) { AString s; // Print_UInt64_and_String(s, _percent.Files == 1 ? "file" : "files", _percent.Files); - PrintPropPair(s, "Files read from disk", _percent.Files); + PrintPropPair(s, "Files read from disk", _percent.Files - NumNonOpenFiles); s.Add_LF(); s += "Archive size: "; PrintSize_bytes_Smart(s, st.OutArcFileSize); s.Add_LF(); + if (st.IsMultiVolMode) + { + s += "Volumes: "; + s.Add_UInt32(st.NumVolumes); + s.Add_LF(); + } *_so << endl; *_so << s; // *_so << endl; @@ -316,7 +353,7 @@ HRESULT CUpdateCallbackConsole::WriteSfx(const wchar_t *name, UInt64 size) { *_so << "Write SFX: "; *_so << name; - AString s = " : "; + AString s (" : "); PrintSize_bytes_Smart(s, size); *_so << s << endl; } @@ -342,6 +379,7 @@ HRESULT CUpdateCallbackConsole::DeletingAfterArchiving(const FString &path, bool _tempA.Add_Space(); *_so << _tempA; _tempU = fs2us(path); + _so->Normalize_UString(_tempU); _so->PrintUString(_tempU, _tempA); *_so << endl; if (NeedFlush) @@ -398,14 +436,31 @@ HRESULT CUpdateCallbackConsole::Finalize() } */ -HRESULT CUpdateCallbackConsole::SetNumItems(UInt64 numItems) + +void static PrintToDoStat(CStdOutStream *_so, const CDirItemsStat2 &stat, const char *name) +{ + AString s; + Print_DirItemsStat2(s, stat); + *_so << name << ": " << s << endl; +} + +HRESULT CUpdateCallbackConsole::SetNumItems(const CArcToDoStat &stat) { if (_so) { ClosePercents_for_so(); - AString s; - PrintPropPair(s, "Items to compress", numItems); - *_so << s << endl << endl; + if (!stat.DeleteData.IsEmpty()) + { + *_so << endl; + PrintToDoStat(_so, stat.DeleteData, "Delete data from archive"); + } + if (!stat.OldData.IsEmpty()) + PrintToDoStat(_so, stat.OldData, "Keep old data in archive"); + // if (!stat.NewData.IsEmpty()) + { + PrintToDoStat(_so, stat.NewData, "Add new data to archive"); + } + *_so << endl; } return S_OK; } @@ -440,7 +495,7 @@ HRESULT CUpdateCallbackConsole::SetRatioInfo(const UInt64 * /* inSize */, const return CheckBreak2(); } -HRESULT CCallbackConsoleBase::PrintProgress(const wchar_t *name, const char *command, bool showInLog) +HRESULT CCallbackConsoleBase::PrintProgress(const wchar_t *name, bool isDir, const char *command, bool showInLog) { MT_LOCK @@ -457,7 +512,12 @@ HRESULT CCallbackConsoleBase::PrintProgress(const wchar_t *name, const char *com _tempU.Empty(); if (name) + { _tempU = name; + if (isDir) + NWindows::NFile::NName::NormalizeDirPathPrefix(_tempU); + _so->Normalize_UString(_tempU); + } _so->PrintUString(_tempU, _tempA); *_so << endl; if (NeedFlush) @@ -483,7 +543,29 @@ HRESULT CCallbackConsoleBase::PrintProgress(const wchar_t *name, const char *com return CheckBreak2(); } -HRESULT CUpdateCallbackConsole::GetStream(const wchar_t *name, bool /* isDir */, bool isAnti, UInt32 mode) + +/* +void CCallbackConsoleBase::PrintInfoLine(const UString &s) +{ + if (LogLevel < 1000) + return; + + MT_LOCK + + const bool show2 = (_so != NULL); + + if (show2) + { + ClosePercents_for_so(); + _so->PrintUString(s, _tempA); + *_so << endl; + if (NeedFlush) + _so->Flush(); + } +} +*/ + +HRESULT CUpdateCallbackConsole::GetStream(const wchar_t *name, bool isDir, bool isAnti, UInt32 mode) { if (StdOutMode) return S_OK; @@ -513,7 +595,7 @@ HRESULT CUpdateCallbackConsole::GetStream(const wchar_t *name, bool /* isDir */, s = "Reading"; } - return PrintProgress(name, s, LogLevel >= requiredLevel); + return PrintProgress(name, isDir, s, LogLevel >= requiredLevel); } HRESULT CUpdateCallbackConsole::OpenFileError(const FString &path, DWORD systemError) @@ -526,10 +608,19 @@ HRESULT CUpdateCallbackConsole::ReadingFileError(const FString &path, DWORD syst return ReadingFileError_Base(path, systemError); } -HRESULT CUpdateCallbackConsole::SetOperationResult(Int32) +HRESULT CUpdateCallbackConsole::SetOperationResult(Int32 /* opRes */) { MT_LOCK _percent.Files++; + /* + if (opRes != NArchive::NUpdate::NOperationResult::kOK) + { + if (opRes == NArchive::NUpdate::NOperationResult::kError_FileChanged) + { + CommonError("Input file changed"); + } + } + */ return S_OK; } @@ -550,7 +641,9 @@ HRESULT CUpdateCallbackConsole::ReportExtractResult(Int32 opRes, Int32 isEncrypt AString s; SetExtractErrorMessage(opRes, isEncrypted, s); - *_se << s << " : " << endl << name << endl << endl; + *_se << s << " : " << endl; + _se->NormalizePrint_wstr(name); + *_se << endl << endl; _se->Flush(); } return S_OK; @@ -559,7 +652,7 @@ HRESULT CUpdateCallbackConsole::ReportExtractResult(Int32 opRes, Int32 isEncrypt } -HRESULT CUpdateCallbackConsole::ReportUpdateOpeartion(UInt32 op, const wchar_t *name, bool /* isDir */) +HRESULT CUpdateCallbackConsole::ReportUpdateOperation(UInt32 op, const wchar_t *name, bool isDir) { // if (StdOutMode) return S_OK; @@ -578,6 +671,8 @@ HRESULT CUpdateCallbackConsole::ReportUpdateOpeartion(UInt32 op, const wchar_t * case NUpdateNotifyOp::kSkip: s = "."; requiredLevel = 2; break; case NUpdateNotifyOp::kDelete: s = "D"; requiredLevel = 3; break; case NUpdateNotifyOp::kHeader: s = "Header creation"; requiredLevel = 100; break; + case NUpdateNotifyOp::kInFileChanged: s = "Size of input file was changed:"; requiredLevel = 10; break; + // case NUpdateNotifyOp::kOpFinished: s = "Finished"; requiredLevel = 100; break; default: { temp[0] = 'o'; @@ -587,17 +682,17 @@ HRESULT CUpdateCallbackConsole::ReportUpdateOpeartion(UInt32 op, const wchar_t * } } - return PrintProgress(name, s, LogLevel >= requiredLevel); + return PrintProgress(name, isDir, s, LogLevel >= requiredLevel); } /* HRESULT CUpdateCallbackConsole::SetPassword(const UString & - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO password #endif ) { - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO PasswordIsDefined = true; Password = password; #endif @@ -611,7 +706,7 @@ HRESULT CUpdateCallbackConsole::CryptoGetTextPassword2(Int32 *passwordIsDefined, *password = NULL; - #ifdef _NO_CRYPTO + #ifdef Z7_NO_CRYPTO *passwordIsDefined = false; return S_OK; @@ -622,7 +717,7 @@ HRESULT CUpdateCallbackConsole::CryptoGetTextPassword2(Int32 *passwordIsDefined, { if (AskPassword) { - Password = GetPassword(_so); + RINOK(GetPassword_HRESULT(_so, Password)) PasswordIsDefined = true; } } @@ -640,7 +735,7 @@ HRESULT CUpdateCallbackConsole::CryptoGetTextPassword(BSTR *password) *password = NULL; - #ifdef _NO_CRYPTO + #ifdef Z7_NO_CRYPTO return E_NOTIMPL; @@ -649,7 +744,7 @@ HRESULT CUpdateCallbackConsole::CryptoGetTextPassword(BSTR *password) if (!PasswordIsDefined) { { - Password = GetPassword(_so); + RINOK(GetPassword_HRESULT(_so, Password)) PasswordIsDefined = true; } } @@ -659,7 +754,7 @@ HRESULT CUpdateCallbackConsole::CryptoGetTextPassword(BSTR *password) COM_TRY_END } -HRESULT CUpdateCallbackConsole::ShowDeleteFile(const wchar_t *name, bool /* isDir */) +HRESULT CUpdateCallbackConsole::ShowDeleteFile(const wchar_t *name, bool isDir) { if (StdOutMode) return S_OK; @@ -668,7 +763,123 @@ HRESULT CUpdateCallbackConsole::ShowDeleteFile(const wchar_t *name, bool /* isDi { if (!name || name[0] == 0) name = kEmptyFileAlias; - return PrintProgress(name, "D", true); + return PrintProgress(name, isDir, "D", true); } return S_OK; } + +/* +void GetPropName(PROPID propID, const wchar_t *name, AString &nameA, UString &nameU); + +static void GetPropName(PROPID propID, UString &nameU) +{ + AString nameA; + GetPropName(propID, NULL, nameA, nameU); + // if (!nameA.IsEmpty()) + nameU = nameA; +} + + +static void AddPropNamePrefix(UString &s, PROPID propID) +{ + UString name; + GetPropName(propID, name); + s += name; + s += " = "; +} + +void CCallbackConsoleBase::PrintPropInfo(UString &s, PROPID propID, const PROPVARIANT *value) +{ + AddPropNamePrefix(s, propID); + { + UString dest; + const int level = 9; // we show up to ns precision level + ConvertPropertyToString2(dest, *value, propID, level); + s += dest; + } + PrintInfoLine(s); +} + +static void Add_IndexType_Index(UString &s, UInt32 indexType, UInt32 index) +{ + if (indexType == NArchive::NEventIndexType::kArcProp) + { + } + else + { + if (indexType == NArchive::NEventIndexType::kBlockIndex) + { + s += "#"; + } + else if (indexType == NArchive::NEventIndexType::kOutArcIndex) + { + } + else + { + s += "indexType_"; + s.Add_UInt32(indexType); + s.Add_Space(); + } + s.Add_UInt32(index); + } + s += ": "; +} + +HRESULT CUpdateCallbackConsole::ReportProp(UInt32 indexType, UInt32 index, PROPID propID, const PROPVARIANT *value) +{ + UString s; + Add_IndexType_Index(s, indexType, index); + PrintPropInfo(s, propID, value); + return S_OK; +} + +static inline char GetHex(Byte value) +{ + return (char)((value < 10) ? ('0' + value) : ('a' + (value - 10))); +} + +static void AddHexToString(UString &dest, const Byte *data, UInt32 size) +{ + for (UInt32 i = 0; i < size; i++) + { + Byte b = data[i]; + dest += GetHex((Byte)((b >> 4) & 0xF)); + dest += GetHex((Byte)(b & 0xF)); + } +} + +void HashHexToString(char *dest, const Byte *data, UInt32 size); + +HRESULT CUpdateCallbackConsole::ReportRawProp(UInt32 indexType, UInt32 index, + PROPID propID, const void *data, UInt32 dataSize, UInt32 propType) +{ + UString s; + propType = propType; + Add_IndexType_Index(s, indexType, index); + AddPropNamePrefix(s, propID); + if (propID == kpidChecksum) + { + char temp[k_HashCalc_DigestSize_Max + 8]; + HashHexToString(temp, (const Byte *)data, dataSize); + s += temp; + } + else + AddHexToString(s, (const Byte *)data, dataSize); + PrintInfoLine(s); + return S_OK; +} + +HRESULT CUpdateCallbackConsole::ReportFinished(UInt32 indexType, UInt32 index, Int32 opRes) +{ + UString s; + Add_IndexType_Index(s, indexType, index); + s += "finished"; + if (opRes != NArchive::NUpdate::NOperationResult::kOK) + { + s += ": "; + s.Add_UInt32(opRes); + } + PrintInfoLine(s); + return S_OK; +} +*/ diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/UpdateCallbackConsole.h b/3rdparty/lzma/CPP/7zip/UI/Console/UpdateCallbackConsole.h index ba8614ebaa3..b6c1be4b749 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/UpdateCallbackConsole.h +++ b/3rdparty/lzma/CPP/7zip/UI/Console/UpdateCallbackConsole.h @@ -1,7 +1,7 @@ // UpdateCallbackConsole.h -#ifndef __UPDATE_CALLBACK_CONSOLE_H -#define __UPDATE_CALLBACK_CONSOLE_H +#ifndef ZIP7_INC_UPDATE_CALLBACK_CONSOLE_H +#define ZIP7_INC_UPDATE_CALLBACK_CONSOLE_H #include "../../../Common/StdOutStream.h" @@ -26,6 +26,7 @@ struct CErrorPathCodes } }; + class CCallbackConsoleBase { protected: @@ -35,13 +36,14 @@ protected: CStdOutStream *_se; void CommonError(const FString &path, DWORD systemError, bool isWarning); - + // void CommonError(const char *message); + HRESULT ScanError_Base(const FString &path, DWORD systemError); HRESULT OpenFileError_Base(const FString &name, DWORD systemError); HRESULT ReadingFileError_Base(const FString &name, DWORD systemError); public: - bool NeedPercents() const { return _percent._so != NULL; }; + bool NeedPercents() const { return _percent._so != NULL; } bool StdOutMode; @@ -56,7 +58,8 @@ public: StdOutMode(false), NeedFlush(false), PercentsNameLevel(1), - LogLevel(0) + LogLevel(0), + NumNonOpenFiles(0) {} void SetWindowWidth(unsigned width) { _percent.MaxLen = width - 1; } @@ -82,35 +85,42 @@ public: _percent.ClosePrint(false); } - CErrorPathCodes FailedFiles; CErrorPathCodes ScanErrors; + UInt64 NumNonOpenFiles; - HRESULT PrintProgress(const wchar_t *name, const char *command, bool showInLog); + HRESULT PrintProgress(const wchar_t *name, bool isDir, const char *command, bool showInLog); + // void PrintInfoLine(const UString &s); + // void PrintPropInfo(UString &s, PROPID propID, const PROPVARIANT *value); }; -class CUpdateCallbackConsole: public IUpdateCallbackUI2, public CCallbackConsoleBase + +class CUpdateCallbackConsole Z7_final: + public IUpdateCallbackUI2, + public CCallbackConsoleBase { // void PrintPropPair(const char *name, const wchar_t *val); - + Z7_IFACE_IMP(IUpdateCallbackUI) + Z7_IFACE_IMP(IDirItemsCallback) + Z7_IFACE_IMP(IUpdateCallbackUI2) public: - #ifndef _NO_CRYPTO + bool DeleteMessageWasShown; + + #ifndef Z7_NO_CRYPTO bool PasswordIsDefined; - UString Password; bool AskPassword; + UString Password; #endif - bool DeleteMessageWasShown; - - CUpdateCallbackConsole() - : DeleteMessageWasShown(false) - #ifndef _NO_CRYPTO + CUpdateCallbackConsole(): + DeleteMessageWasShown(false) + #ifndef Z7_NO_CRYPTO , PasswordIsDefined(false) , AskPassword(false) #endif {} - + /* void Init(CStdOutStream *outStream) { @@ -118,7 +128,6 @@ public: } */ // ~CUpdateCallbackConsole() { if (NeedPercents()) _percent.ClosePrint(); } - INTERFACE_IUpdateCallbackUI2(;) }; #endif diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/UserInputUtils.cpp b/3rdparty/lzma/CPP/7zip/UI/Console/UserInputUtils.cpp index c7f830ff999..04d675e6f83 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/UserInputUtils.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Console/UserInputUtils.cpp @@ -14,8 +14,8 @@ static const char kNoAll = 's'; static const char kAutoRenameAll = 'u'; static const char kQuit = 'q'; -static const char *kFirstQuestionMessage = "? "; -static const char *kHelpQuestionMessage = +static const char * const kFirstQuestionMessage = "? "; +static const char * const kHelpQuestionMessage = "(Y)es / (N)o / (A)lways / (S)kip all / A(u)to rename all / (Q)uit? "; // return true if pressed Quite; @@ -31,9 +31,16 @@ NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream) *outStream << kHelpQuestionMessage; outStream->Flush(); } - AString scannedString = g_StdIn.ScanStringUntilNewLine(); + AString scannedString; + if (!g_StdIn.ScanAStringUntilNewLine(scannedString)) + return NUserAnswerMode::kError; + if (g_StdIn.Error()) + return NUserAnswerMode::kError; scannedString.Trim(); - if (!scannedString.IsEmpty()) + if (scannedString.IsEmpty() && g_StdIn.Eof()) + return NUserAnswerMode::kEof; + + if (scannedString.Len() == 1) switch (::MyCharLower_Ascii(scannedString[0])) { case kYes: return NUserAnswerMode::kYes; @@ -52,7 +59,7 @@ NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream) #endif #endif -UString GetPassword(CStdOutStream *outStream) +static bool GetPassword(CStdOutStream *outStream, UString &psw) { if (outStream) { @@ -66,25 +73,45 @@ UString GetPassword(CStdOutStream *outStream) #ifdef MY_DISABLE_ECHO - HANDLE console = GetStdHandle(STD_INPUT_HANDLE); + const HANDLE console = GetStdHandle(STD_INPUT_HANDLE); + + /* + GetStdHandle() returns + INVALID_HANDLE_VALUE: If the function fails. + NULL : If an application does not have associated standard handles, + such as a service running on an interactive desktop, + and has not redirected them. */ bool wasChanged = false; DWORD mode = 0; - if (console != INVALID_HANDLE_VALUE && console != 0) + if (console != INVALID_HANDLE_VALUE && console != NULL) if (GetConsoleMode(console, &mode)) - wasChanged = (SetConsoleMode(console, mode & ~ENABLE_ECHO_INPUT) != 0); - UString res = g_StdIn.ScanUStringUntilNewLine(); + wasChanged = (SetConsoleMode(console, mode & ~(DWORD)ENABLE_ECHO_INPUT) != 0); + const bool res = g_StdIn.ScanUStringUntilNewLine(psw); if (wasChanged) SetConsoleMode(console, mode); + + #else + + const bool res = g_StdIn.ScanUStringUntilNewLine(psw); + + #endif + if (outStream) { *outStream << endl; outStream->Flush(); } + return res; - - #else - - return g_StdIn.ScanUStringUntilNewLine(); - - #endif +} + +HRESULT GetPassword_HRESULT(CStdOutStream *outStream, UString &psw) +{ + if (!GetPassword(outStream, psw)) + return E_INVALIDARG; + if (g_StdIn.Error()) + return E_FAIL; + if (g_StdIn.Eof() && psw.IsEmpty()) + return E_ABORT; + return S_OK; } diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/UserInputUtils.h b/3rdparty/lzma/CPP/7zip/UI/Console/UserInputUtils.h index 16f045803e4..695a3e66da7 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/UserInputUtils.h +++ b/3rdparty/lzma/CPP/7zip/UI/Console/UserInputUtils.h @@ -1,7 +1,7 @@ // UserInputUtils.h -#ifndef __USER_INPUT_UTILS_H -#define __USER_INPUT_UTILS_H +#ifndef ZIP7_INC_USER_INPUT_UTILS_H +#define ZIP7_INC_USER_INPUT_UTILS_H #include "../../../Common/StdOutStream.h" @@ -14,11 +14,14 @@ enum EEnum kYesAll, kNoAll, kAutoRenameAll, - kQuit + kQuit, + kEof, + kError }; } NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream); -UString GetPassword(CStdOutStream *outStream); +// bool GetPassword(CStdOutStream *outStream, UString &psw); +HRESULT GetPassword_HRESULT(CStdOutStream *outStream, UString &psw); #endif diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/makefile b/3rdparty/lzma/CPP/7zip/UI/Console/makefile index 98ad91c2440..a20b0cc0b5c 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/makefile +++ b/3rdparty/lzma/CPP/7zip/UI/Console/makefile @@ -1,15 +1,11 @@ PROG = 7z.exe -MY_CONSOLE = 1 CFLAGS = $(CFLAGS) \ - -DEXTERNAL_CODECS \ - -!IFNDEF UNDER_CE -CFLAGS = $(CFLAGS) -DWIN_LONG_PATH -D_7ZIP_LARGE_PAGES -DSUPPORT_DEVICE_FILE -!ENDIF + -DZ7_EXTERNAL_CODECS \ COMMON_OBJS = \ $O\CommandLineParser.obj \ $O\CRC.obj \ + $O\DynLimBuf.obj \ $O\IntToString.obj \ $O\ListFileUtils.obj \ $O\NewHandler.obj \ @@ -36,6 +32,7 @@ WIN_OBJS = \ $O\PropVariantConv.obj \ $O\Registry.obj \ $O\System.obj \ + $O\SystemInfo.obj \ $O\TimeUtils.obj \ 7ZIP_COMMON_OBJS = \ @@ -45,6 +42,7 @@ WIN_OBJS = \ $O\FilterCoder.obj \ $O\LimitedStreams.obj \ $O\MethodProps.obj \ + $O\MultiOutStream.obj \ $O\ProgressUtils.obj \ $O\PropId.obj \ $O\StreamObjects.obj \ @@ -52,12 +50,13 @@ WIN_OBJS = \ $O\UniqBlocks.obj \ AR_COMMON_OBJS = \ + $O\ItemNameUtils.obj \ $O\OutStreamWithCRC.obj \ COMPRESS_OBJS = \ $O\CopyCoder.obj \ -C_OBJS = \ +C_OBJS = $(C_OBJS) \ $O\Alloc.obj \ $O\CpuArch.obj \ $O\Sort.obj \ diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/makefile.gcc b/3rdparty/lzma/CPP/7zip/UI/Console/makefile.gcc new file mode 100644 index 00000000000..8a293d8ac91 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/Console/makefile.gcc @@ -0,0 +1,186 @@ +PROG = 7z +IS_NOT_STANDALONE = 1 + +# IS_X64 = 1 +# USE_ASM = 1 +# ST_MODE = 1 + + +LOCAL_FLAGS_ST = +MT_OBJS = + +ifdef SystemDrive +IS_MINGW = 1 +else +ifdef SYSTEMDRIVE +# ifdef OS +IS_MINGW = 1 +endif +endif + +ifdef ST_MODE + +LOCAL_FLAGS_ST = -DZ7_ST + +ifdef IS_MINGW +MT_OBJS = \ + $O/Threads.o \ + +endif + +else + +MT_OBJS = \ + $O/Synchronization.o \ + $O/Threads.o \ + +endif + + + +LOCAL_FLAGS_WIN= + +ifdef IS_MINGW + +LOCAL_FLAGS_WIN = \ + -DZ7_LARGE_PAGES \ + -DZ7_LONG_PATH \ + -DZ7_DEVICE_FILE \ + +SYS_OBJS = \ + $O/FileSystem.o \ + $O/Registry.o \ + $O/MemoryLock.o \ + $O/DllSecur.o \ + $O/resource.o \ + +else + +SYS_OBJS = \ + $O/MyWindows.o \ + +endif + + + +LOCAL_FLAGS = \ + $(LOCAL_FLAGS_WIN) \ + $(LOCAL_FLAGS_ST) \ + -DZ7_EXTERNAL_CODECS \ + + + +CONSOLE_OBJS = \ + $O/BenchCon.o \ + $O/ConsoleClose.o \ + $O/ExtractCallbackConsole.o \ + $O/HashCon.o \ + $O/List.o \ + $O/Main.o \ + $O/MainAr.o \ + $O/OpenCallbackConsole.o \ + $O/PercentPrinter.o \ + $O/UpdateCallbackConsole.o \ + $O/UserInputUtils.o \ + +UI_COMMON_OBJS = \ + $O/ArchiveCommandLine.o \ + $O/ArchiveExtractCallback.o \ + $O/ArchiveOpenCallback.o \ + $O/Bench.o \ + $O/DefaultName.o \ + $O/EnumDirItems.o \ + $O/Extract.o \ + $O/ExtractingFilePath.o \ + $O/HashCalc.o \ + $O/LoadCodecs.o \ + $O/OpenArchive.o \ + $O/PropIDUtils.o \ + $O/SetProperties.o \ + $O/SortUtils.o \ + $O/TempFiles.o \ + $O/Update.o \ + $O/UpdateAction.o \ + $O/UpdateCallback.o \ + $O/UpdatePair.o \ + $O/UpdateProduce.o \ + +COMMON_OBJS = \ + $O/CommandLineParser.o \ + $O/CRC.o \ + $O/CrcReg.o \ + $O/DynLimBuf.o \ + $O/IntToString.o \ + $O/ListFileUtils.o \ + $O/NewHandler.o \ + $O/StdInStream.o \ + $O/StdOutStream.o \ + $O/MyString.o \ + $O/StringConvert.o \ + $O/StringToInt.o \ + $O/UTFConvert.o \ + $O/MyVector.o \ + $O/Wildcard.o \ + +WIN_OBJS = \ + $O/DLL.o \ + $O/ErrorMsg.o \ + $O/FileDir.o \ + $O/FileFind.o \ + $O/FileIO.o \ + $O/FileLink.o \ + $O/FileName.o \ + $O/PropVariant.o \ + $O/PropVariantConv.o \ + $O/System.o \ + $O/SystemInfo.o \ + $O/TimeUtils.o \ + +7ZIP_COMMON_OBJS = \ + $O/CreateCoder.o \ + $O/CWrappers.o \ + $O/FilePathAutoRename.o \ + $O/FileStreams.o \ + $O/InBuffer.o \ + $O/InOutTempBuffer.o \ + $O/FilterCoder.o \ + $O/LimitedStreams.o \ + $O/MethodId.o \ + $O/MethodProps.o \ + $O/MultiOutStream.o \ + $O/OffsetStream.o \ + $O/OutBuffer.o \ + $O/ProgressUtils.o \ + $O/PropId.o \ + $O/StreamObjects.o \ + $O/StreamUtils.o \ + $O/UniqBlocks.o \ + +COMPRESS_OBJS = \ + $O/CopyCoder.o \ + +AR_COMMON_OBJS = \ + $O/ItemNameUtils.o \ + +C_OBJS = \ + $O/Alloc.o \ + $O/CpuArch.o \ + $O/Sort.o \ + $O/7zCrc.o \ + $O/7zCrcOpt.o \ + + +OBJS = \ + $(C_OBJS) \ + $(MT_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(SYS_OBJS) \ + $(COMPRESS_OBJS) \ + $(AR_COMMON_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(UI_COMMON_OBJS) \ + $(CONSOLE_OBJS) \ + + +include ../../7zip_gcc.mak diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/resource.rc b/3rdparty/lzma/CPP/7zip/UI/Console/resource.rc index 6e09bb968be..414427fb2d1 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/resource.rc +++ b/3rdparty/lzma/CPP/7zip/UI/Console/resource.rc @@ -1,3 +1,7 @@ #include "../../MyVersionInfo.rc" -MY_VERSION_INFO_APP("7-Zip Console", "7z") +MY_VERSION_INFO_APP("7-Zip Console" , "7z") + +#ifndef UNDER_CE +1 24 MOVEABLE PURE "Console.manifest" +#endif diff --git a/3rdparty/lzma/CPP/7zip/UI/Explorer/MyMessages.cpp b/3rdparty/lzma/CPP/7zip/UI/Explorer/MyMessages.cpp index 70c2a4608d3..daff7dedbcf 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Explorer/MyMessages.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Explorer/MyMessages.cpp @@ -18,15 +18,18 @@ void ShowErrorMessage(HWND window, LPCWSTR message) void ShowErrorMessageHwndRes(HWND window, UINT resID) { - ShowErrorMessage(window, LangString(resID)); + UString s = LangString(resID); + if (s.IsEmpty()) + s.Add_UInt32(resID); + ShowErrorMessage(window, s); } void ShowErrorMessageRes(UINT resID) { - ShowErrorMessageHwndRes(0, resID); + ShowErrorMessageHwndRes(NULL, resID); } -void ShowErrorMessageDWORD(HWND window, DWORD errorCode) +static void ShowErrorMessageDWORD(HWND window, DWORD errorCode) { ShowErrorMessage(window, NError::MyFormatMessage(errorCode)); } diff --git a/3rdparty/lzma/CPP/7zip/UI/Explorer/MyMessages.h b/3rdparty/lzma/CPP/7zip/UI/Explorer/MyMessages.h index d5822f45f1c..47d10db71c8 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Explorer/MyMessages.h +++ b/3rdparty/lzma/CPP/7zip/UI/Explorer/MyMessages.h @@ -1,16 +1,16 @@ // MyMessages.h -#ifndef __MY_MESSAGES_H -#define __MY_MESSAGES_H +#ifndef ZIP7_INC_MY_MESSAGES_H +#define ZIP7_INC_MY_MESSAGES_H #include "../../../Common/MyString.h" void ShowErrorMessage(HWND window, LPCWSTR message); -inline void ShowErrorMessage(LPCWSTR message) { ShowErrorMessage(0, message); } +inline void ShowErrorMessage(LPCWSTR message) { ShowErrorMessage(NULL, message); } void ShowErrorMessageHwndRes(HWND window, UInt32 langID); void ShowErrorMessageRes(UInt32 langID); -void ShowLastErrorMessage(HWND window = 0); +void ShowLastErrorMessage(HWND window = NULL); #endif diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/BrowseDialog.cpp b/3rdparty/lzma/CPP/7zip/UI/FileManager/BrowseDialog.cpp index 066ac219190..5170302c332 100644 --- a/3rdparty/lzma/CPP/7zip/UI/FileManager/BrowseDialog.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/BrowseDialog.cpp @@ -4,7 +4,7 @@ #include "../../../Common/MyWindows.h" -#include <commctrl.h> +#include "../../../Common/IntToString.h" #ifndef UNDER_CE #include "../../../Windows/CommonDialog.h" @@ -25,7 +25,6 @@ #ifdef USE_MY_BROWSE_DIALOG #include "../../../Common/Defs.h" -#include "../../../Common/IntToString.h" #include "../../../Common/Wildcard.h" #include "../../../Windows/FileDir.h" @@ -40,11 +39,11 @@ #include "PropertyNameRes.h" #include "SysIconUtils.h" -#ifndef _SFX +#ifndef Z7_SFX #include "RegistryUtils.h" #endif -#endif +#endif // USE_MY_BROWSE_DIALOG #include "ComboDialog.h" #include "LangUtils.h" @@ -56,6 +55,11 @@ using namespace NFile; using namespace NName; using namespace NFind; +static void MessageBox_Error_Global(HWND wnd, const wchar_t *message) +{ + ::MessageBoxW(wnd, message, L"7-Zip", MB_ICONERROR); +} + #ifdef USE_MY_BROWSE_DIALOG extern bool g_LVN_ITEMACTIVATE_Support; @@ -63,19 +67,8 @@ extern bool g_LVN_ITEMACTIVATE_Support; static const int kParentIndex = -1; static const UINT k_Message_RefreshPathEdit = WM_APP + 1; -static HRESULT GetNormalizedError() -{ - DWORD errorCode = GetLastError(); - return errorCode == 0 ? E_FAIL : errorCode; -} - extern UString HResultToMessage(HRESULT errorCode); -static void MessageBox_Error_Global(HWND wnd, const wchar_t *message) -{ - ::MessageBoxW(wnd, message, L"7-Zip", MB_ICONERROR); -} - static void MessageBox_HResError(HWND wnd, HRESULT errorCode, const wchar_t *name) { UString s = HResultToMessage(errorCode); @@ -98,17 +91,21 @@ class CBrowseDialog: public NControl::CModalDialog CExtToIconMap _extToIconMap; int _sortIndex; bool _ascending; + #ifndef Z7_SFX bool _showDots; + #endif UString _topDirPrefix; // we don't open parent of that folder UString DirPrefix; - virtual bool OnInit(); - virtual bool OnSize(WPARAM wParam, int xSize, int ySize); - virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam); - virtual bool OnNotify(UINT controlID, LPNMHDR header); - virtual bool OnKeyDown(LPNMLVKEYDOWN keyDownInfo); - virtual bool OnButtonClicked(int buttonID, HWND buttonHWND); - virtual void OnOK(); + virtual bool OnInit() Z7_override; + virtual bool OnSize(WPARAM wParam, int xSize, int ySize) Z7_override; + virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam) Z7_override; + virtual bool OnNotify(UINT controlID, LPNMHDR header) Z7_override; + virtual bool OnCommand(unsigned code, unsigned itemID, LPARAM lParam) Z7_override; + virtual bool OnButtonClicked(unsigned buttonID, HWND buttonHWND) Z7_override; + virtual void OnOK() Z7_override; + + bool OnKeyDown(LPNMLVKEYDOWN keyDownInfo); void Post_RefreshPathEdit() { PostMsg(k_Message_RefreshPathEdit); } @@ -126,59 +123,37 @@ class CBrowseDialog: public NControl::CModalDialog int GetRealItemIndex(int indexInListView) const { LPARAM param; - if (!_list.GetItemParam(indexInListView, param)) + if (!_list.GetItemParam((unsigned)indexInListView, param)) return (int)-1; return (int)param; } public: + + bool SaveMode; bool FolderMode; + int FilterIndex; // [in / out] + CObjectVector<CBrowseFilterInfo> Filters; + + UString FilePath; // [in / out] UString Title; - UString FilePath; // input/ result path - bool ShowAllFiles; - UStringVector Filters; - UString FilterDescription; - - CBrowseDialog(): FolderMode(false), _showDots(false), ShowAllFiles(true) {} - void SetFilter(const UString &s); - INT_PTR Create(HWND parent = 0) { return CModalDialog::Create(IDD_BROWSE, parent); } - int CompareItems(LPARAM lParam1, LPARAM lParam2); + + CBrowseDialog(): + #ifndef Z7_SFX + _showDots(false), + #endif + SaveMode(false) + , FolderMode(false) + , FilterIndex(-1) + {} + INT_PTR Create(HWND parent = NULL) { return CModalDialog::Create(IDD_BROWSE, parent); } + int CompareItems(LPARAM lParam1, LPARAM lParam2) const; }; -void CBrowseDialog::SetFilter(const UString &s) -{ - Filters.Clear(); - UString mask; - unsigned i; - for (i = 0; i < s.Len(); i++) - { - wchar_t c = s[i]; - if (c == ';') - { - if (!mask.IsEmpty()) - Filters.Add(mask); - mask.Empty(); - } - else - mask += c; - } - if (!mask.IsEmpty()) - Filters.Add(mask); - ShowAllFiles = Filters.IsEmpty(); - for (i = 0; i < Filters.Size(); i++) - { - const UString &f = Filters[i]; - if (f == L"*.*" || f == L"*") - { - ShowAllFiles = true; - break; - } - } -} bool CBrowseDialog::OnInit() { - #ifdef LANG + #ifdef Z7_LANG LangSetDlgItems(*this, NULL, 0); #endif if (!Title.IsEmpty()) @@ -187,16 +162,11 @@ bool CBrowseDialog::OnInit() _filterCombo.Attach(GetItem(IDC_BROWSE_FILTER)); _pathEdit.Attach(GetItem(IDE_BROWSE_PATH)); - if (FolderMode) - HideItem(IDC_BROWSE_FILTER); - else - EnableItem(IDC_BROWSE_FILTER, false); - #ifndef UNDER_CE _list.SetUnicodeFormat(); #endif - #ifndef _SFX + #ifndef Z7_SFX CFmSettings st; st.Load(); if (st.SingleClick) @@ -205,22 +175,34 @@ bool CBrowseDialog::OnInit() #endif { - UString s; - if (!FilterDescription.IsEmpty()) - s = FilterDescription; - else if (ShowAllFiles) - s = L"*.*"; - else + /* + Filters.Clear(); // for debug + if (Filters.IsEmpty() && !FolderMode) { - FOR_VECTOR (i, Filters) - { - if (i != 0) - s.Add_Space(); - s += Filters[i]; - } + CBrowseFilterInfo &f = Filters.AddNew(); + const UString mask("*.*"); + f.Masks.Add(mask); + // f.Description = "("; + f.Description += mask; + // f.Description += ")"; + } + */ + + FOR_VECTOR (i, Filters) + { + _filterCombo.AddString(Filters[i].Description); + } + + if (Filters.Size() <= 1) + { + if (FolderMode) + HideItem(IDC_BROWSE_FILTER); + else + EnableItem(IDC_BROWSE_FILTER, false); } - _filterCombo.AddString(s); - _filterCombo.SetCurSel(0); + + if (/* FilterIndex >= 0 && */ (unsigned)FilterIndex < Filters.Size()) + _filterCombo.SetCurSel(FilterIndex); } _list.SetImageList(GetSysImageList(true), LVSIL_SMALL); @@ -235,7 +217,7 @@ bool CBrowseDialog::OnInit() column.fmt = LVCFMT_RIGHT; column.cx = 100; const UString s = LangString(IDS_PROP_SIZE); - column.pszText = (wchar_t *)(const wchar_t *)s; + column.pszText = s.Ptr_non_const(); _list.InsertColumn(2, &column); } @@ -261,7 +243,7 @@ bool CBrowseDialog::OnInit() _topDirPrefix.Empty(); { - int rootSize = GetRootPrefixSize(FilePath); + unsigned rootSize = GetRootPrefixSize(FilePath); #if defined(_WIN32) && !defined(UNDER_CE) // We can go up from root folder to drives list if (IsDrivePath(FilePath)) @@ -301,7 +283,7 @@ bool CBrowseDialog::OnInit() #ifndef UNDER_CE /* If we clear UISF_HIDEFOCUS, the focus rectangle in ListView will be visible, even if we use mouse for pressing the button to open this dialog. */ - PostMsg(MY__WM_UPDATEUISTATE, MAKEWPARAM(MY__UIS_CLEAR, MY__UISF_HIDEFOCUS)); + PostMsg(Z7_WIN_WM_UPDATEUISTATE, MAKEWPARAM(Z7_WIN_UIS_CLEAR, Z7_WIN_UISF_HIDEFOCUS)); #endif return CModalDialog::OnInit(); @@ -368,6 +350,24 @@ bool CBrowseDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) return CModalDialog::OnMessage(message, wParam, lParam); } + +bool CBrowseDialog::OnCommand(unsigned code, unsigned itemID, LPARAM lParam) +{ + if (code == CBN_SELCHANGE) + { + switch (itemID) + { + case IDC_BROWSE_FILTER: + { + Reload(); + return true; + } + } + } + return CModalDialog::OnCommand(code, itemID, lParam); +} + + bool CBrowseDialog::OnNotify(UINT /* controlID */, LPNMHDR header) { if (header->hwndFrom != _list) @@ -385,7 +385,7 @@ bool CBrowseDialog::OnNotify(UINT /* controlID */, LPNMHDR header) break; case LVN_COLUMNCLICK: { - int index = LPNMLISTVIEW(header)->iSubItem; + const int index = LPNMLISTVIEW(header)->iSubItem; if (index == _sortIndex) _ascending = !_ascending; else @@ -413,7 +413,7 @@ bool CBrowseDialog::OnNotify(UINT /* controlID */, LPNMHDR header) bool CBrowseDialog::OnKeyDown(LPNMLVKEYDOWN keyDownInfo) { - bool ctrl = IsKeyDown(VK_CONTROL); + const bool ctrl = IsKeyDown(VK_CONTROL); switch (keyDownInfo->wVKey) { @@ -434,7 +434,8 @@ bool CBrowseDialog::OnKeyDown(LPNMLVKEYDOWN keyDownInfo) return false; } -bool CBrowseDialog::OnButtonClicked(int buttonID, HWND buttonHWND) + +bool CBrowseDialog::OnButtonClicked(unsigned buttonID, HWND buttonHWND) { switch (buttonID) { @@ -468,27 +469,27 @@ bool CBrowseDialog::GetParentPath(const UString &path, UString &parentPrefix, US if (_topDirPrefix == path) return false; UString s = path; - if (s.Back() == WCHAR_PATH_SEPARATOR) + if (IS_PATH_SEPAR(s.Back())) s.DeleteBack(); if (s.IsEmpty()) return false; - if (s.Back() == WCHAR_PATH_SEPARATOR) + if (IS_PATH_SEPAR(s.Back())) return false; - int pos = s.ReverseFind_PathSepar(); - parentPrefix.SetFrom(s, pos + 1); - name = s.Ptr(pos + 1); + const unsigned pos1 = (unsigned)(s.ReverseFind_PathSepar() + 1); + parentPrefix.SetFrom(s, pos1); + name = s.Ptr(pos1); return true; } -int CBrowseDialog::CompareItems(LPARAM lParam1, LPARAM lParam2) +int CBrowseDialog::CompareItems(LPARAM lParam1, LPARAM lParam2) const { if (lParam1 == kParentIndex) return -1; if (lParam2 == kParentIndex) return 1; const CFileInfo &f1 = _files[(int)lParam1]; const CFileInfo &f2 = _files[(int)lParam2]; - bool isDir1 = f1.IsDir(); - bool isDir2 = f2.IsDir(); + const bool isDir1 = f1.IsDir(); + const bool isDir2 = f2.IsDir(); if (isDir1 && !isDir2) return -1; if (isDir2 && !isDir1) return 1; @@ -509,16 +510,16 @@ static int CALLBACK CompareItems2(LPARAM lParam1, LPARAM lParam2, LPARAM lpData) static void ConvertSizeToString(UInt64 v, wchar_t *s) { - Byte c = 0; + char c = 0; if (v >= ((UInt64)10000 << 20)) { v >>= 30; c = 'G'; } else if (v >= ((UInt64)10000 << 10)) { v >>= 20; c = 'M'; } else if (v >= ((UInt64)10000 << 0)) { v >>= 10; c = 'K'; } - ConvertUInt64ToString(v, s); + s = ConvertUInt64ToString(v, s); if (c != 0) { - s += MyStringLen(s); *s++ = ' '; - *s++ = c; + *s++ = (wchar_t)c; + *s++ = 'B'; *s++ = 0; } } @@ -531,46 +532,62 @@ HRESULT CBrowseDialog::Reload(const UString &pathPrefix, const UString &selected #ifndef UNDER_CE bool isDrive = false; - if (pathPrefix.IsEmpty() || pathPrefix == kSuperPathPrefix) + if (pathPrefix.IsEmpty() || pathPrefix.IsEqualTo(kSuperPathPrefix)) { isDrive = true; FStringVector drives; if (!MyGetLogicalDriveStrings(drives)) - return GetNormalizedError(); + return GetLastError_noZero_HRESULT(); FOR_VECTOR (i, drives) { - FString d = drives[i]; - if (d.Len() < 3 || d.Back() != '\\') + const FString &d = drives[i]; + if (d.Len() < 2 || d.Back() != '\\') return E_FAIL; - d.DeleteBack(); CFileInfo &fi = files.AddNew(); fi.SetAsDir(); fi.Name = d; + fi.Name.DeleteBack(); } } else #endif { - CEnumerator enumerator(us2fs(pathPrefix + L'*')); + const UStringVector *masks = NULL; + if (!Filters.IsEmpty() && _filterCombo.GetCount() > 0) + { + const int selected = _filterCombo.GetCurSel(); + // GetItemData_of_CurSel(); // we don't use data field + if (/* selected >= 0 && */ (unsigned)selected < Filters.Size()) + { + const UStringVector &m = Filters[selected].Masks; + if (m.Size() > 1 || (m.Size() == 1 + && !m[0].IsEqualTo("*.*") + && !m[0].IsEqualTo("*"))) + masks = &m; + } + } + CEnumerator enumerator; + enumerator.SetDirPrefix(us2fs(pathPrefix)); + CFileInfo fi; for (;;) { bool found; - CFileInfo fi; if (!enumerator.Next(fi, found)) - return GetNormalizedError(); + return GetLastError_noZero_HRESULT(); if (!found) break; if (!fi.IsDir()) { if (FolderMode) continue; - if (!ShowAllFiles) + if (masks) { unsigned i; - for (i = 0; i < Filters.Size(); i++) - if (DoesWildcardMatchName(Filters[i], fs2us(fi.Name))) + const unsigned numMasks = masks->Size(); + for (i = 0; i < numMasks; i++) + if (DoesWildcardMatchName((*masks)[i], fs2us(fi.Name))) break; - if (i == Filters.Size()) + if (i == numMasks) continue; } } @@ -589,21 +606,21 @@ HRESULT CBrowseDialog::Reload(const UString &pathPrefix, const UString &selected LVITEMW item; - int index = 0; + unsigned index = 0; int cursorIndex = -1; - #ifndef _SFX + #ifndef Z7_SFX if (_showDots && _topDirPrefix != DirPrefix) { - item.iItem = index; - const UString itemName = L".."; + item.iItem = (int)index; + const UString itemName (".."); if (selectedName.IsEmpty()) - cursorIndex = index; + cursorIndex = (int)index; item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE; - int subItem = 0; - item.iSubItem = subItem++; + unsigned subItem = 0; + item.iSubItem = (int)(subItem++); item.lParam = kParentIndex; - item.pszText = (wchar_t *)(const wchar_t *)itemName; + item.pszText = itemName.Ptr_non_const(); item.iImage = _extToIconMap.GetIconIndex(FILE_ATTRIBUTE_DIRECTORY, DirPrefix); if (item.iImage < 0) item.iImage = 0; @@ -616,16 +633,16 @@ HRESULT CBrowseDialog::Reload(const UString &pathPrefix, const UString &selected for (unsigned i = 0; i < _files.Size(); i++, index++) { - item.iItem = index; + item.iItem = (int)index; const CFileInfo &fi = _files[i]; const UString name = fs2us(fi.Name); if (!selectedName.IsEmpty() && CompareFileNames(name, selectedName) == 0) - cursorIndex = index; + cursorIndex = (int)index; item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE; - int subItem = 0; - item.iSubItem = subItem++; - item.lParam = i; - item.pszText = (wchar_t *)(const wchar_t *)name; + unsigned subItem = 0; + item.iSubItem = (int)(subItem++); + item.lParam = (LPARAM)i; + item.pszText = name.Ptr_non_const(); const UString fullPath = DirPrefix + name; #ifndef UNDER_CE @@ -642,16 +659,14 @@ HRESULT CBrowseDialog::Reload(const UString &pathPrefix, const UString &selected _list.InsertItem(&item); wchar_t s[32]; { - FILETIME ft; s[0] = 0; - if (FileTimeToLocalFileTime(&fi.MTime, &ft)) - ConvertFileTimeToString(ft, s, + ConvertUtcFileTimeToString(fi.MTime, s, #ifndef UNDER_CE - true + kTimestampPrintLevel_MIN #else - false + kTimestampPrintLevel_DAY #endif - , false); + ); _list.SetSubItem(index, subItem++, s); } { @@ -676,14 +691,14 @@ HRESULT CBrowseDialog::Reload(const UString &pathPrefix, const UString &selected HRESULT CBrowseDialog::Reload() { UString selected; - int index = _list.GetNextSelectedItem(-1); + const int index = _list.GetNextSelectedItem(-1); if (index >= 0) { - int fileIndex = GetRealItemIndex(index); + const int fileIndex = GetRealItemIndex(index); if (fileIndex != kParentIndex) selected = fs2us(_files[fileIndex].Name); } - UString dirPathTemp = DirPrefix; + const UString dirPathTemp = DirPrefix; return Reload(dirPathTemp, selected); } @@ -699,14 +714,14 @@ void CBrowseDialog::OpenParentFolder() void CBrowseDialog::SetPathEditText() { - int index = _list.GetNextSelectedItem(-1); + const int index = _list.GetNextSelectedItem(-1); if (index < 0) { if (FolderMode) _pathEdit.SetText(DirPrefix); return; } - int fileIndex = GetRealItemIndex(index); + const int fileIndex = GetRealItemIndex(index); if (fileIndex == kParentIndex) { if (FolderMode) @@ -746,7 +761,7 @@ void CBrowseDialog::OnCreateDir() { if (!NDir::CreateComplexDir(destPath)) { - MessageBox_HResError((HWND)*this, GetNormalizedError(), fs2us(destPath)); + MessageBox_HResError((HWND)*this, GetLastError_noZero_HRESULT(), fs2us(destPath)); } else { @@ -760,10 +775,10 @@ void CBrowseDialog::OnCreateDir() void CBrowseDialog::OnItemEnter() { - int index = _list.GetNextSelectedItem(-1); + const int index = _list.GetNextSelectedItem(-1); if (index < 0) return; - int fileIndex = GetRealItemIndex(index); + const int fileIndex = GetRealItemIndex(index); if (fileIndex == kParentIndex) OpenParentFolder(); else @@ -780,8 +795,10 @@ void CBrowseDialog::OnItemEnter() */ return; } - UString s = DirPrefix + fs2us(file.Name) + WCHAR_PATH_SEPARATOR; - HRESULT res = Reload(s, L""); + UString s = DirPrefix; + s += fs2us(file.Name); + s.Add_PathSepar(); + const HRESULT res = Reload(s, UString()); if (res != S_OK) MessageBox_HResError(*this, res, s); SetPathEditText(); @@ -801,10 +818,13 @@ void CBrowseDialog::FinishOnOK() FilePath = fs2us(destPath); if (FolderMode) NormalizeDirPathPrefix(FilePath); + FilterIndex = _filterCombo.GetCurSel(); End(IDOK); } -#endif +#endif // USE_MY_BROWSE_DIALOG + + bool MyBrowseForFolder(HWND owner, LPCWSTR title, LPCWSTR path, UString &resultPath) { @@ -812,12 +832,13 @@ bool MyBrowseForFolder(HWND owner, LPCWSTR title, LPCWSTR path, UString &resultP #ifndef UNDER_CE - #ifdef USE_MY_BROWSE_DIALOG +#ifdef USE_MY_BROWSE_DIALOG if (!IsSuperOrDevicePath(path)) - #endif + if (MyStringLen(path) < MAX_PATH) +#endif return NShell::BrowseForFolder(owner, title, path, resultPath); - #endif + #endif // UNDER_CE #ifdef USE_MY_BROWSE_DIALOG @@ -830,64 +851,107 @@ bool MyBrowseForFolder(HWND owner, LPCWSTR title, LPCWSTR path, UString &resultP if (dialog.Create(owner) != IDOK) return false; resultPath = dialog.FilePath; - #endif - return true; + + #endif } -bool MyBrowseForFile(HWND owner, LPCWSTR title, LPCWSTR path, - LPCWSTR filterDescription, LPCWSTR filter, UString &resultPath) -{ - resultPath.Empty(); - #ifndef UNDER_CE +// LPCWSTR filterDescription, LPCWSTR filter, - #ifdef USE_MY_BROWSE_DIALOG - if (!IsSuperOrDevicePath(path)) - #endif +bool CBrowseInfo::BrowseForFile(const CObjectVector<CBrowseFilterInfo> &filters) +{ +#ifndef UNDER_CE +#ifdef USE_MY_BROWSE_DIALOG + /* win10: + GetOpenFileName() for FilePath doesn't support super prefix "\\\\?\\" + GetOpenFileName() for FilePath doesn't support long path + */ + if (!IsSuperOrDevicePath(FilePath)) + // if (filters.Size() > 100) // for debug +#endif { - if (MyGetOpenFileName(owner, title, NULL, path, filterDescription, filter, resultPath)) + const UString filePath_Store = FilePath; + UString dirPrefix; + { + FString prefix, name; + if (NDir::GetFullPathAndSplit(us2fs(FilePath), prefix, name)) + { + dirPrefix = fs2us(prefix); + FilePath = fs2us(name); + } + } + UStringVector filters2; + FOR_VECTOR (i, filters) + { + const CBrowseFilterInfo &fi = filters[i]; + filters2.Add(fi.Description); + UString s; + FOR_VECTOR (k, fi.Masks) + { + if (k != 0) + s += ";"; + s += fi.Masks[k]; + } + filters2.Add(s); + } + if (CommonDlg_BrowseForFile(!dirPrefix.IsEmpty() ? dirPrefix.Ptr(): NULL, filters2)) return true; - #ifdef UNDER_CE + FilePath = filePath_Store; + + #ifdef UNDER_CE return false; - #else + #else // maybe we must use GetLastError in WinCE. - DWORD errorCode = CommDlgExtendedError(); - const wchar_t *errorMessage = NULL; - switch (errorCode) - { - case 0: return false; // cancel or close obn dialog - case FNERR_INVALIDFILENAME: errorMessage = L"Invalid File Name"; break; - default: errorMessage = L"Open Dialog Error"; - } - if (!errorMessage) - return false; + const DWORD errorCode = CommDlgExtendedError(); + #ifdef USE_MY_BROWSE_DIALOG + // FNERR_INVALIDFILENAME is expected error, if long path was used + if (errorCode != FNERR_INVALIDFILENAME + || FilePath.Len() < MAX_PATH) + #endif { - UString s = errorMessage; + if (errorCode == 0) // cancel or close on dialog + return false; + const char *message = NULL; + if (errorCode == FNERR_INVALIDFILENAME) + message = "Invalid file name"; + UString s ("Open Dialog Error:"); + s.Add_LF(); + if (message) + s += message; + else + { + char temp[16]; + ConvertUInt32ToHex8Digits(errorCode, temp); + s += "Error #"; + s += temp; + } s.Add_LF(); - s += path; - MessageBox_Error_Global(owner, s); + s += FilePath; + MessageBox_Error_Global(hwndOwner, s); } - #endif + #endif // UNDER_CE } - #endif +#endif // UNDER_CE - #ifdef USE_MY_BROWSE_DIALOG +#ifdef USE_MY_BROWSE_DIALOG + CBrowseDialog dialog; - if (title) - dialog.Title = title; - if (path) - dialog.FilePath = path; + dialog.FolderMode = false; - if (filter) - dialog.SetFilter(filter); - if (filterDescription) - dialog.FilterDescription = filterDescription; - if (dialog.Create(owner) != IDOK) + dialog.SaveMode = SaveMode; + dialog.FilterIndex = FilterIndex; + dialog.Filters = filters; + + if (lpstrTitle) + dialog.Title = lpstrTitle; + dialog.FilePath = FilePath; + if (dialog.Create(hwndOwner) != IDOK) return false; - resultPath = dialog.FilePath; - #endif + FilePath = dialog.FilePath; + FilterIndex = dialog.FilterIndex; +#endif return true; } @@ -912,7 +976,9 @@ bool CorrectFsPath(const UString &relBase, const UString &path2, UString &result result.Empty(); UString path = path2; + #ifdef _WIN32 path.Replace(L'/', WCHAR_PATH_SEPARATOR); + #endif unsigned start = 0; UString base; @@ -925,9 +991,7 @@ bool CorrectFsPath(const UString &relBase, const UString &path2, UString &result return true; } #endif - int pos = GetRootPrefixSize(path); - if (pos > 0) - start = pos; + start = GetRootPrefixSize(path); } else { @@ -952,7 +1016,7 @@ bool CorrectFsPath(const UString &relBase, const UString &path2, UString &result if (path.Back() == WCHAR_PATH_SEPARATOR) { path.DeleteBack(); - result.Insert(0, WCHAR_PATH_SEPARATOR);; + result.Insert(0, WCHAR_PATH_SEPARATOR); } int pos = path.ReverseFind(WCHAR_PATH_SEPARATOR) + 1; UString cur = path.Ptr(pos); @@ -972,8 +1036,8 @@ bool CorrectFsPath(const UString &relBase, const UString &path2, UString &result { if (start == path.Len()) break; - int slashPos = path.Find(WCHAR_PATH_SEPARATOR, start); - cur.SetFrom(path.Ptr(start), (slashPos < 0 ? path.Len() : slashPos) - start); + const int slashPos = path.Find(WCHAR_PATH_SEPARATOR, start); + cur.SetFrom(path.Ptr(start), (slashPos < 0 ? path.Len() : (unsigned)slashPos) - start); if (checkExist) { CFileInfo fi; @@ -993,8 +1057,8 @@ bool CorrectFsPath(const UString &relBase, const UString &path2, UString &result result += cur; if (slashPos < 0) break; + start = (unsigned)(slashPos + 1); result.Add_PathSepar(); - start = slashPos + 1; } return true; diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/BrowseDialog.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/BrowseDialog.h index 957af2e2577..2ad8d5443a3 100644 --- a/3rdparty/lzma/CPP/7zip/UI/FileManager/BrowseDialog.h +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/BrowseDialog.h @@ -1,12 +1,23 @@ // BrowseDialog.h -#ifndef __BROWSE_DIALOG_H -#define __BROWSE_DIALOG_H +#ifndef ZIP7_INC_BROWSE_DIALOG_H +#define ZIP7_INC_BROWSE_DIALOG_H -#include "../../../Common/MyString.h" +#include "../../../Windows/CommonDialog.h" bool MyBrowseForFolder(HWND owner, LPCWSTR title, LPCWSTR path, UString &resultPath); -bool MyBrowseForFile(HWND owner, LPCWSTR title, LPCWSTR path, LPCWSTR filterDescription, LPCWSTR filter, UString &resultPath); + +struct CBrowseFilterInfo +{ + UStringVector Masks; + UString Description; +}; + +struct CBrowseInfo: public NWindows::CCommonDialogInfo +{ + bool BrowseForFile(const CObjectVector<CBrowseFilterInfo> &filters); +}; + /* CorrectFsPath removes undesirable characters in names (dots and spaces at the end of file) But it doesn't change "bad" name in any of the following cases: diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/ComboDialog.cpp b/3rdparty/lzma/CPP/7zip/UI/FileManager/ComboDialog.cpp index 729743e8795..921972eab10 100644 --- a/3rdparty/lzma/CPP/7zip/UI/FileManager/ComboDialog.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/ComboDialog.cpp @@ -5,7 +5,7 @@ #include "../../../Windows/Control/Static.h" -#ifdef LANG +#ifdef Z7_LANG #include "LangUtils.h" #endif @@ -13,7 +13,7 @@ using namespace NWindows; bool CComboDialog::OnInit() { - #ifdef LANG + #ifdef Z7_LANG LangSetDlgItems(*this, NULL, 0); #endif _comboBox.Attach(GetItem(IDC_COMBO)); diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/ComboDialog.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/ComboDialog.h index 29b28b5b49c..bb0fda80e16 100644 --- a/3rdparty/lzma/CPP/7zip/UI/FileManager/ComboDialog.h +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/ComboDialog.h @@ -1,7 +1,7 @@ // ComboDialog.h -#ifndef __COMBO_DIALOG_H -#define __COMBO_DIALOG_H +#ifndef ZIP7_INC_COMBO_DIALOG_H +#define ZIP7_INC_COMBO_DIALOG_H #include "../../../Windows/Control/ComboBox.h" #include "../../../Windows/Control/Dialog.h" @@ -11,9 +11,9 @@ class CComboDialog: public NWindows::NControl::CModalDialog { NWindows::NControl::CComboBox _comboBox; - virtual void OnOK(); - virtual bool OnInit(); - virtual bool OnSize(WPARAM wParam, int xSize, int ySize); + virtual void OnOK() Z7_override; + virtual bool OnInit() Z7_override; + virtual bool OnSize(WPARAM wParam, int xSize, int ySize) Z7_override; public: // bool Sorted; UString Title; @@ -22,7 +22,7 @@ public: UStringVector Strings; // CComboDialog(): Sorted(false) {}; - INT_PTR Create(HWND parentWindow = 0) { return CModalDialog::Create(IDD_COMBO, parentWindow); } + INT_PTR Create(HWND parentWindow = NULL) { return CModalDialog::Create(IDD_COMBO, parentWindow); } }; #endif diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/DialogSize.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/DialogSize.h index 504541bdf3c..9f2270bd40e 100644 --- a/3rdparty/lzma/CPP/7zip/UI/FileManager/DialogSize.h +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/DialogSize.h @@ -1,7 +1,7 @@ // DialogSize.h -#ifndef __DIALOG_SIZE_H -#define __DIALOG_SIZE_H +#ifndef ZIP7_INC_DIALOG_SIZE_H +#define ZIP7_INC_DIALOG_SIZE_H #include "../../../Windows/Control/Dialog.h" diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/ExtractCallback.cpp b/3rdparty/lzma/CPP/7zip/UI/FileManager/ExtractCallback.cpp index 7d61d14d9d9..f67404479b0 100644 --- a/3rdparty/lzma/CPP/7zip/UI/FileManager/ExtractCallback.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/ExtractCallback.cpp @@ -17,7 +17,7 @@ #include "../../Common/StreamUtils.h" #include "../Common/ExtractingFilePath.h" -#ifndef _SFX +#ifndef Z7_SFX #include "../Common/ZipRegistry.h" #endif @@ -28,7 +28,7 @@ #include "FormatUtils.h" #include "LangUtils.h" #include "OverwriteDialog.h" -#ifndef _NO_CRYPTO +#ifndef Z7_NO_CRYPTO #include "PasswordDialog.h" #endif #include "PropertyName.h" @@ -44,10 +44,11 @@ void CExtractCallbackImp::Init() _lang_Extracting = LangString(IDS_PROGRESS_EXTRACTING); _lang_Testing = LangString(IDS_PROGRESS_TESTING); _lang_Skipping = LangString(IDS_PROGRESS_SKIPPING); + _lang_Reading = "Reading"; NumArchiveErrors = 0; ThereAreMessageErrors = false; - #ifndef _SFX + #ifndef Z7_SFX NumFolders = NumFiles = 0; NeedAddFile = false; #endif @@ -59,29 +60,27 @@ void CExtractCallbackImp::AddError_Message(LPCWSTR s) ProgressDialog->Sync.AddError_Message(s); } -#ifndef _SFX +#ifndef Z7_SFX -STDMETHODIMP CExtractCallbackImp::SetNumFiles(UInt64 - #ifndef _SFX - numFiles - #endif - ) +Z7_COM7F_IMF(CExtractCallbackImp::SetNumFiles(UInt64 numFiles)) { - #ifndef _SFX + #ifdef Z7_SFX + UNUSED_VAR(numFiles) + #else ProgressDialog->Sync.Set_NumFilesTotal(numFiles); - #endif + #endif return S_OK; } #endif -STDMETHODIMP CExtractCallbackImp::SetTotal(UInt64 total) +Z7_COM7F_IMF(CExtractCallbackImp::SetTotal(UInt64 total)) { ProgressDialog->Sync.Set_NumBytesTotal(total); return S_OK; } -STDMETHODIMP CExtractCallbackImp::SetCompleted(const UInt64 *value) +Z7_COM7F_IMF(CExtractCallbackImp::SetCompleted(const UInt64 *value)) { return ProgressDialog->Sync.Set_NumBytesCur(value); } @@ -138,7 +137,7 @@ HRESULT CExtractCallbackImp::Open_Finished() return ProgressDialog->Sync.CheckStop(); } -#ifndef _NO_CRYPTO +#ifndef Z7_NO_CRYPTO HRESULT CExtractCallbackImp::Open_CryptoGetTextPassword(BSTR *password) { @@ -167,8 +166,8 @@ void CExtractCallbackImp::Open_Clear_PasswordWasAsked_Flag() #endif -#ifndef _SFX -STDMETHODIMP CExtractCallbackImp::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) +#ifndef Z7_SFX +Z7_COM7F_IMF(CExtractCallbackImp::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)) { ProgressDialog->Sync.Set_Ratio(inSize, outSize); return S_OK; @@ -176,13 +175,13 @@ STDMETHODIMP CExtractCallbackImp::SetRatioInfo(const UInt64 *inSize, const UInt6 #endif /* -STDMETHODIMP CExtractCallbackImp::SetTotalFiles(UInt64 total) +Z7_COM7F_IMF(CExtractCallbackImp::SetTotalFiles(UInt64 total) { ProgressDialog->Sync.SetNumFilesTotal(total); return S_OK; } -STDMETHODIMP CExtractCallbackImp::SetCompletedFiles(const UInt64 *value) +Z7_COM7F_IMF(CExtractCallbackImp::SetCompletedFiles(const UInt64 *value) { if (value != NULL) ProgressDialog->Sync.SetNumFilesCur(*value); @@ -190,10 +189,10 @@ STDMETHODIMP CExtractCallbackImp::SetCompletedFiles(const UInt64 *value) } */ -STDMETHODIMP CExtractCallbackImp::AskOverwrite( +Z7_COM7F_IMF(CExtractCallbackImp::AskOverwrite( const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize, const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize, - Int32 *answer) + Int32 *answer)) { COverwriteDialog dialog; @@ -222,7 +221,7 @@ STDMETHODIMP CExtractCallbackImp::AskOverwrite( } -STDMETHODIMP CExtractCallbackImp::PrepareOperation(const wchar_t *name, Int32 isFolder, Int32 askExtractMode, const UInt64 * /* position */) +Z7_COM7F_IMF(CExtractCallbackImp::PrepareOperation(const wchar_t *name, Int32 isFolder, Int32 askExtractMode, const UInt64 * /* position */)) { _isFolder = IntToBool(isFolder); _currentFilePath = name; @@ -233,13 +232,14 @@ STDMETHODIMP CExtractCallbackImp::PrepareOperation(const wchar_t *name, Int32 is case NArchive::NExtract::NAskMode::kExtract: msg = &_lang_Extracting; break; case NArchive::NExtract::NAskMode::kTest: msg = &_lang_Testing; break; case NArchive::NExtract::NAskMode::kSkip: msg = &_lang_Skipping; break; + case NArchive::NExtract::NAskMode::kReadExternal: msg = &_lang_Reading; break; // default: s = "Unknown operation"; } return ProgressDialog->Sync.Set_Status2(*msg, name, IntToBool(isFolder)); } -STDMETHODIMP CExtractCallbackImp::MessageError(const wchar_t *s) +Z7_COM7F_IMF(CExtractCallbackImp::MessageError(const wchar_t *s)) { AddError_Message(s); return S_OK; @@ -252,9 +252,9 @@ HRESULT CExtractCallbackImp::MessageError(const char *message, const FString &pa return S_OK; } -#ifndef _SFX +#ifndef Z7_SFX -STDMETHODIMP CExtractCallbackImp::ShowMessage(const wchar_t *s) +Z7_COM7F_IMF(CExtractCallbackImp::ShowMessage(const wchar_t *s)) { AddError_Message(s); return S_OK; @@ -262,6 +262,7 @@ STDMETHODIMP CExtractCallbackImp::ShowMessage(const wchar_t *s) #endif +void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, const wchar_t *fileName, UString &s); void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, const wchar_t *fileName, UString &s) { s.Empty(); @@ -269,25 +270,33 @@ void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, const wchar_t *fileNam if (opRes == NArchive::NExtract::NOperationResult::kOK) return; + #ifndef Z7_SFX UINT messageID = 0; + #endif UINT id = 0; switch (opRes) { case NArchive::NExtract::NOperationResult::kUnsupportedMethod: + #ifndef Z7_SFX messageID = IDS_EXTRACT_MESSAGE_UNSUPPORTED_METHOD; + #endif id = IDS_EXTRACT_MSG_UNSUPPORTED_METHOD; break; case NArchive::NExtract::NOperationResult::kDataError: + #ifndef Z7_SFX messageID = encrypted ? IDS_EXTRACT_MESSAGE_DATA_ERROR_ENCRYPTED: IDS_EXTRACT_MESSAGE_DATA_ERROR; + #endif id = IDS_EXTRACT_MSG_DATA_ERROR; break; case NArchive::NExtract::NOperationResult::kCRCError: + #ifndef Z7_SFX messageID = encrypted ? IDS_EXTRACT_MESSAGE_CRC_ERROR_ENCRYPTED: IDS_EXTRACT_MESSAGE_CRC_ERROR; + #endif id = IDS_EXTRACT_MSG_CRC_ERROR; break; case NArchive::NExtract::NOperationResult::kUnavailable: @@ -316,18 +325,19 @@ void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, const wchar_t *fileNam } UString msg; - UString msgOld; - #ifndef _SFX + #ifndef Z7_SFX + UString msgOld; + #ifdef Z7_LANG if (id != 0) LangString_OnlyFromLangFile(id, msg); if (messageID != 0 && msg.IsEmpty()) LangString_OnlyFromLangFile(messageID, msgOld); - #endif - + #endif if (msg.IsEmpty() && !msgOld.IsEmpty()) s = MyFormatNew(msgOld, fileName); else + #endif { if (msg.IsEmpty() && id != 0) LangString(id, msg); @@ -335,25 +345,23 @@ void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, const wchar_t *fileNam s += msg; else { - char temp[16]; - ConvertUInt32ToString(opRes, temp); - s.AddAscii("Error #"); - s.AddAscii(temp); + s += "Error #"; + s.Add_UInt32((UInt32)opRes); } if (encrypted && opRes != NArchive::NExtract::NOperationResult::kWrongPassword) { - // s.AddAscii(" : "); + // s += " : "; // AddLangString(s, IDS_EXTRACT_MSG_ENCRYPTED); - s.AddAscii(" : "); + s += " : "; AddLangString(s, IDS_EXTRACT_MSG_WRONG_PSW_GUESS); } - s.AddAscii(" : "); + s += " : "; s += fileName; } } -STDMETHODIMP CExtractCallbackImp::SetOperationResult(Int32 opRes, Int32 encrypted) +Z7_COM7F_IMF(CExtractCallbackImp::SetOperationResult(Int32 opRes, Int32 encrypted)) { switch (opRes) { @@ -368,7 +376,7 @@ STDMETHODIMP CExtractCallbackImp::SetOperationResult(Int32 opRes, Int32 encrypte } } - #ifndef _SFX + #ifndef Z7_SFX if (_isFolder) NumFolders++; else @@ -379,7 +387,7 @@ STDMETHODIMP CExtractCallbackImp::SetOperationResult(Int32 opRes, Int32 encrypte return S_OK; } -STDMETHODIMP CExtractCallbackImp::ReportExtractResult(Int32 opRes, Int32 encrypted, const wchar_t *name) +Z7_COM7F_IMF(CExtractCallbackImp::ReportExtractResult(Int32 opRes, Int32 encrypted, const wchar_t *name)) { if (opRes != NArchive::NExtract::NOperationResult::kOK) { @@ -396,8 +404,8 @@ STDMETHODIMP CExtractCallbackImp::ReportExtractResult(Int32 opRes, Int32 encrypt HRESULT CExtractCallbackImp::BeforeOpen(const wchar_t *name, bool /* testMode */) { - #ifndef _SFX - RINOK(ProgressDialog->Sync.CheckStop()); + #ifndef Z7_SFX + RINOK(ProgressDialog->Sync.CheckStop()) ProgressDialog->Sync.Set_TitleFileName(name); #endif _currentArchivePath = name; @@ -407,17 +415,17 @@ HRESULT CExtractCallbackImp::BeforeOpen(const wchar_t *name, bool /* testMode */ HRESULT CExtractCallbackImp::SetCurrentFilePath2(const wchar_t *path) { _currentFilePath = path; - #ifndef _SFX + #ifndef Z7_SFX ProgressDialog->Sync.Set_FilePath(path); #endif return S_OK; } -#ifndef _SFX +#ifndef Z7_SFX -HRESULT CExtractCallbackImp::SetCurrentFilePath(const wchar_t *path) +Z7_COM7F_IMF(CExtractCallbackImp::SetCurrentFilePath(const wchar_t *path)) { - #ifndef _SFX + #ifndef Z7_SFX if (NeedAddFile) NumFiles++; NeedAddFile = true; @@ -451,11 +459,12 @@ static void AddNewLineString(UString &s, const UString &m) s.Add_LF(); } +UString GetOpenArcErrorMessage(UInt32 errorFlags); UString GetOpenArcErrorMessage(UInt32 errorFlags) { UString s; - for (unsigned i = 0; i < ARRAY_SIZE(k_ErrorFlagsIds); i++) + for (unsigned i = 0; i < Z7_ARRAY_SIZE(k_ErrorFlagsIds); i++) { UInt32 f = ((UInt32)1 << i); if ((errorFlags & f) == 0) @@ -466,7 +475,7 @@ UString GetOpenArcErrorMessage(UInt32 errorFlags) continue; if (f == kpv_ErrorFlags_EncryptedHeadersError) { - m.AddAscii(" : "); + m += " : "; AddLangString(m, IDS_EXTRACT_MSG_WRONG_PSW_GUESS); } if (!s.IsEmpty()) @@ -483,7 +492,7 @@ UString GetOpenArcErrorMessage(UInt32 errorFlags) ConvertUInt32ToHex(errorFlags, sz + 2); if (!s.IsEmpty()) s.Add_LF(); - s.AddAscii(sz); + s += sz; } return s; @@ -503,7 +512,7 @@ static void ErrorInfo_Print(UString &s, const CArcErrorInfo &er) if (warningFlags != 0) { s += GetNameOfProperty(kpidWarningFlags, L"Warnings"); - s.AddAscii(":"); + s += ":"; s.Add_LF(); AddNewLineString(s, GetOpenArcErrorMessage(warningFlags)); } @@ -511,7 +520,7 @@ static void ErrorInfo_Print(UString &s, const CArcErrorInfo &er) if (!er.WarningMessage.IsEmpty()) { s += GetNameOfProperty(kpidWarning, L"Warning"); - s.AddAscii(": "); + s += ": "; s += er.WarningMessage; s.Add_LF(); } @@ -519,12 +528,13 @@ static void ErrorInfo_Print(UString &s, const CArcErrorInfo &er) static UString GetBracedType(const wchar_t *type) { - UString s = L'['; + UString s ('['); s += type; - s += L']'; + s += ']'; return s; } +void OpenResult_GUI(UString &s, const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result); void OpenResult_GUI(UString &s, const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result) { FOR_VECTOR (level, arcLink.Arcs) @@ -634,7 +644,9 @@ HRESULT CExtractCallbackImp::ExtractResult(HRESULT result) if (result == S_OK) return result; NumArchiveErrors++; - if (result == E_ABORT || result == ERROR_DISK_FULL) + if (result == E_ABORT + || result == HRESULT_FROM_WIN32(ERROR_DISK_FULL) + ) return result; Add_ArchiveName_Error(); @@ -644,7 +656,7 @@ HRESULT CExtractCallbackImp::ExtractResult(HRESULT result) return S_OK; } -#ifndef _NO_CRYPTO +#ifndef Z7_NO_CRYPTO HRESULT CExtractCallbackImp::SetPassword(const UString &password) { @@ -653,14 +665,14 @@ HRESULT CExtractCallbackImp::SetPassword(const UString &password) return S_OK; } -STDMETHODIMP CExtractCallbackImp::CryptoGetTextPassword(BSTR *password) +Z7_COM7F_IMF(CExtractCallbackImp::CryptoGetTextPassword(BSTR *password)) { PasswordWasAsked = true; if (!PasswordIsDefined) { CPasswordDialog dialog; - #ifndef _SFX - bool showPassword = NExtract::Read_ShowPassword(); + #ifndef Z7_SFX + const bool showPassword = NExtract::Read_ShowPassword(); dialog.ShowPassword = showPassword; #endif ProgressDialog->WaitCreating(); @@ -668,7 +680,7 @@ STDMETHODIMP CExtractCallbackImp::CryptoGetTextPassword(BSTR *password) return E_ABORT; Password = dialog.Password; PasswordIsDefined = true; - #ifndef _SFX + #ifndef Z7_SFX if (dialog.ShowPassword != showPassword) NExtract::Save_ShowPassword(dialog.ShowPassword); #endif @@ -678,24 +690,24 @@ STDMETHODIMP CExtractCallbackImp::CryptoGetTextPassword(BSTR *password) #endif -#ifndef _SFX +#ifndef Z7_SFX -STDMETHODIMP CExtractCallbackImp::AskWrite( +Z7_COM7F_IMF(CExtractCallbackImp::AskWrite( const wchar_t *srcPath, Int32 srcIsFolder, const FILETIME *srcTime, const UInt64 *srcSize, const wchar_t *destPath, BSTR *destPathResult, - Int32 *writeAnswer) + Int32 *writeAnswer)) { UString destPathResultTemp = destPath; // RINOK(StringToBstr(destPath, destPathResult)); - *destPathResult = 0; + *destPathResult = NULL; *writeAnswer = BoolToInt(false); FString destPathSys = us2fs(destPath); - bool srcIsFolderSpec = IntToBool(srcIsFolder); + const bool srcIsFolderSpec = IntToBool(srcIsFolder); CFileInfo destFileInfo; if (destFileInfo.Find(destPathSys)) @@ -704,7 +716,7 @@ STDMETHODIMP CExtractCallbackImp::AskWrite( { if (!destFileInfo.IsDir()) { - RINOK(MessageError("can not replace file with folder with same name", destPathSys)); + RINOK(MessageError("Cannot replace file with folder with same name", destPathSys)) return E_ABORT; } *writeAnswer = BoolToInt(false); @@ -713,12 +725,12 @@ STDMETHODIMP CExtractCallbackImp::AskWrite( if (destFileInfo.IsDir()) { - RINOK(MessageError("can not replace folder with file with same name", destPathSys)); + RINOK(MessageError("Cannot replace folder with file with same name", destPathSys)) *writeAnswer = BoolToInt(false); return S_OK; } - switch (OverwriteMode) + switch ((int)OverwriteMode) { case NExtract::NOverwriteMode::kSkip: return S_OK; @@ -726,8 +738,8 @@ STDMETHODIMP CExtractCallbackImp::AskWrite( { Int32 overwriteResult; UString destPathSpec = destPath; - int slashPos = destPathSpec.ReverseFind_PathSepar(); - destPathSpec.DeleteFrom(slashPos + 1); + const int slashPos = destPathSpec.ReverseFind_PathSepar(); + destPathSpec.DeleteFrom((unsigned)(slashPos + 1)); destPathSpec += fs2us(destFileInfo.Name); RINOK(AskOverwrite( @@ -735,7 +747,7 @@ STDMETHODIMP CExtractCallbackImp::AskWrite( &destFileInfo.MTime, &destFileInfo.Size, srcPath, srcTime, srcSize, - &overwriteResult)); + &overwriteResult)) switch (overwriteResult) { @@ -748,31 +760,38 @@ STDMETHODIMP CExtractCallbackImp::AskWrite( default: return E_FAIL; } + break; } + default: + break; } if (OverwriteMode == NExtract::NOverwriteMode::kRename) { if (!AutoRenamePath(destPathSys)) { - RINOK(MessageError("can not create name for file", destPathSys)); + RINOK(MessageError("Cannot create name for file", destPathSys)) return E_ABORT; } destPathResultTemp = fs2us(destPathSys); } else + { + if (NFind::DoesFileExist_Raw(destPathSys)) if (!NDir::DeleteFileAlways(destPathSys)) + if (GetLastError() != ERROR_FILE_NOT_FOUND) { - RINOK(MessageError("can not delete output file", destPathSys)); + RINOK(MessageError("Cannot delete output file", destPathSys)) return E_ABORT; } + } } *writeAnswer = BoolToInt(true); return StringToBstr(destPathResultTemp, destPathResult); } -STDMETHODIMP CExtractCallbackImp::UseExtractToStream(Int32 *res) +Z7_COM7F_IMF(CExtractCallbackImp::UseExtractToStream(Int32 *res)) { *res = BoolToInt(StreamMode); return S_OK; @@ -782,7 +801,7 @@ static HRESULT GetTime(IGetProp *getProp, PROPID propID, FILETIME &ft, bool &ftD { ftDefined = false; NCOM::CPropVariant prop; - RINOK(getProp->GetProp(propID, &prop)); + RINOK(getProp->GetProp(propID, &prop)) if (prop.vt == VT_FILETIME) { ft = prop.filetime; @@ -798,7 +817,7 @@ static HRESULT GetItemBoolProp(IGetProp *getProp, PROPID propID, bool &result) { NCOM::CPropVariant prop; result = false; - RINOK(getProp->GetProp(propID, &prop)); + RINOK(getProp->GetProp(propID, &prop)) if (prop.vt == VT_BOOL) result = VARIANT_BOOLToBool(prop.boolVal); else if (prop.vt != VT_EMPTY) @@ -807,13 +826,13 @@ static HRESULT GetItemBoolProp(IGetProp *getProp, PROPID propID, bool &result) } -STDMETHODIMP CExtractCallbackImp::GetStream7(const wchar_t *name, +Z7_COM7F_IMF(CExtractCallbackImp::GetStream7(const wchar_t *name, Int32 isDir, ISequentialOutStream **outStream, Int32 askExtractMode, - IGetProp *getProp) + IGetProp *getProp)) { COM_TRY_BEGIN - *outStream = 0; + *outStream = NULL; _newVirtFileWasAdded = false; _hashStreamWasUsed = false; _needUpdateStat = false; @@ -829,20 +848,20 @@ STDMETHODIMP CExtractCallbackImp::GetStream7(const wchar_t *name, _filePath = name; _isFolder = IntToBool(isDir); _curSize = 0; - _curSizeDefined = false; + _curSize_Defined = false; UInt64 size = 0; bool sizeDefined; { NCOM::CPropVariant prop; - RINOK(getProp->GetProp(kpidSize, &prop)); + RINOK(getProp->GetProp(kpidSize, &prop)) sizeDefined = ConvertPropVariantToUInt64(prop, size); } if (sizeDefined) { _curSize = size; - _curSizeDefined = true; + _curSize_Defined = true; } if (askExtractMode != NArchive::NExtract::NAskMode::kExtract && @@ -862,12 +881,12 @@ STDMETHODIMP CExtractCallbackImp::GetStream7(const wchar_t *name, file.IsAltStream = _isAltStream; file.Size = 0; - RINOK(GetTime(getProp, kpidCTime, file.CTime, file.CTimeDefined)); - RINOK(GetTime(getProp, kpidATime, file.ATime, file.ATimeDefined)); - RINOK(GetTime(getProp, kpidMTime, file.MTime, file.MTimeDefined)); + RINOK(GetTime(getProp, kpidCTime, file.CTime, file.CTimeDefined)) + RINOK(GetTime(getProp, kpidATime, file.ATime, file.ATimeDefined)) + RINOK(GetTime(getProp, kpidMTime, file.MTime, file.MTimeDefined)) NCOM::CPropVariant prop; - RINOK(getProp->GetProp(kpidAttrib, &prop)); + RINOK(getProp->GetProp(kpidAttrib, &prop)) if (prop.vt == VT_UI4) { file.Attrib = prop.ulVal; @@ -897,12 +916,14 @@ STDMETHODIMP CExtractCallbackImp::GetStream7(const wchar_t *name, COM_TRY_END } -STDMETHODIMP CExtractCallbackImp::PrepareOperation7(Int32 askExtractMode) +Z7_COM7F_IMF(CExtractCallbackImp::PrepareOperation7(Int32 askExtractMode)) { COM_TRY_BEGIN _needUpdateStat = ( - askExtractMode == NArchive::NExtract::NAskMode::kExtract || - askExtractMode == NArchive::NExtract::NAskMode::kTest); + askExtractMode == NArchive::NExtract::NAskMode::kExtract + || askExtractMode == NArchive::NExtract::NAskMode::kTest + || askExtractMode == NArchive::NExtract::NAskMode::kReadExternal + ); /* _extractMode = false; @@ -920,27 +941,27 @@ STDMETHODIMP CExtractCallbackImp::PrepareOperation7(Int32 askExtractMode) COM_TRY_END } -STDMETHODIMP CExtractCallbackImp::SetOperationResult7(Int32 opRes, Int32 encrypted) +Z7_COM7F_IMF(CExtractCallbackImp::SetOperationResult8(Int32 opRes, Int32 encrypted, UInt64 size)) { COM_TRY_BEGIN if (VirtFileSystem && _newVirtFileWasAdded) { // FIXME: probably we must request file size from VirtFileSystem // _curSize = VirtFileSystem->GetLastFileSize() - // _curSizeDefined = true; - RINOK(VirtFileSystemSpec->CloseMemFile()); + // _curSize_Defined = true; + RINOK(VirtFileSystemSpec->CloseMemFile()) } if (_hashStream && _hashStreamWasUsed) { _hashStreamSpec->_hash->Final(_isFolder, _isAltStream, _filePath); _curSize = _hashStreamSpec->GetSize(); - _curSizeDefined = true; + _curSize_Defined = true; _hashStreamSpec->ReleaseStream(); _hashStreamWasUsed = false; } else if (_hashCalc && _needUpdateStat) { - _hashCalc->SetSize(_curSize); + _hashCalc->SetSize(size); // (_curSize) before 21.04 _hashCalc->Final(_isFolder, _isAltStream, _filePath); } return SetOperationResult(opRes, encrypted); @@ -948,11 +969,10 @@ STDMETHODIMP CExtractCallbackImp::SetOperationResult7(Int32 opRes, Int32 encrypt } -static const size_t k_SizeT_MAX = (size_t)((size_t)0 - 1); -static const UInt32 kBlockSize = ((UInt32)1 << 31); +// static const UInt32 kBlockSize = ((UInt32)1 << 31); -STDMETHODIMP CVirtFileSystem::Write(const void *data, UInt32 size, UInt32 *processedSize) +Z7_COM7F_IMF(CVirtFileSystem::Write(const void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; @@ -975,8 +995,9 @@ STDMETHODIMP CVirtFileSystem::Write(const void *data, UInt32 size, UInt32 *proce if (b < a) b = a; useMem = false; - if (b <= k_SizeT_MAX && b <= MaxTotalAllocSize) - useMem = file.Data.ReAlloc_KeepData((size_t)b, (size_t)file.Size); + const size_t b_sizet = (size_t)b; + if (b == b_sizet && b <= MaxTotalAllocSize) + useMem = file.Data.ReAlloc_KeepData(b_sizet, (size_t)file.Size); } if (useMem) { @@ -988,7 +1009,7 @@ STDMETHODIMP CVirtFileSystem::Write(const void *data, UInt32 size, UInt32 *proce } _fileMode = true; } - RINOK(FlushToDisk(false)); + RINOK(FlushToDisk(false)) return _outFileStream->Write(data, size, processedSize); } @@ -1009,10 +1030,10 @@ HRESULT CVirtFileSystem::FlushToDisk(bool closeLast) { _outFileStream.Release(); return E_FAIL; - // MessageBoxMyError(UString(L"Can't create file ") + fs2us(tempFilePath)); + // MessageBoxMyError(UString("Can't create file ") + fs2us(tempFilePath)); } _fileIsOpen = true; - RINOK(WriteStream(_outFileStream, file.Data, (size_t)file.Size)); + RINOK(WriteStream(_outFileStream, file.Data, (size_t)file.Size)) } if (_numFlushed == Files.Size() - 1 && !closeLast) break; @@ -1027,7 +1048,7 @@ HRESULT CVirtFileSystem::FlushToDisk(bool closeLast) _numFlushed++; _fileIsOpen = false; if (file.AttribDefined) - NDir::SetFileAttrib(path, file.Attrib); + NDir::SetFileAttrib_PosixHighDetect(path, file.Attrib); } return S_OK; } diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/ExtractCallback.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/ExtractCallback.h index 6cd8d0aa83d..c2aa4700c85 100644 --- a/3rdparty/lzma/CPP/7zip/UI/FileManager/ExtractCallback.h +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/ExtractCallback.h @@ -1,42 +1,42 @@ // ExtractCallback.h -#ifndef __EXTRACT_CALLBACK_H -#define __EXTRACT_CALLBACK_H +#ifndef ZIP7_INC_EXTRACT_CALLBACK_H +#define ZIP7_INC_EXTRACT_CALLBACK_H #include "../../../../C/Alloc.h" #include "../../../Common/MyCom.h" #include "../../../Common/StringConvert.h" -#ifndef _SFX +#ifndef Z7_SFX #include "../Agent/IFolderArchive.h" #endif #include "../Common/ArchiveExtractCallback.h" #include "../Common/ArchiveOpenCallback.h" -#ifndef _NO_CRYPTO +#ifndef Z7_NO_CRYPTO #include "../../IPassword.h" #endif -#ifndef _SFX +#ifndef Z7_SFX #include "IFolder.h" #endif #include "ProgressDialog2.h" -#ifdef LANG -#include "LangUtils.h" +#ifdef Z7_LANG +// #include "LangUtils.h" #endif -#ifndef _SFX +#ifndef Z7_SFX class CGrowBuf { Byte *_items; size_t _size; - CLASS_NO_COPY(CGrowBuf); + Z7_CLASS_NO_COPY(CGrowBuf) public: bool ReAlloc_KeepData(size_t newSize, size_t keepSize) @@ -52,7 +52,7 @@ public: return true; } - CGrowBuf(): _items(0), _size(0) {} + CGrowBuf(): _items(NULL), _size(0) {} ~CGrowBuf() { MyFree(_items); } operator Byte *() { return _items; } @@ -92,10 +92,11 @@ struct CVirtFile IsAltStream(false) {} }; -class CVirtFileSystem: - public ISequentialOutStream, - public CMyUnknownImp -{ + +Z7_CLASS_IMP_NOQIB_1( + CVirtFileSystem, + ISequentialOutStream +) UInt64 _totalAllocSize; size_t _pos; @@ -156,104 +157,86 @@ public: HRESULT CloseFile(const FString &path); HRESULT FlushToDisk(bool closeLast); size_t GetPos() const { return _pos; } - - MY_UNKNOWN_IMP - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); }; #endif -class CExtractCallbackImp: - public IExtractCallbackUI, // it includes IFolderArchiveExtractCallback - public IOpenCallbackUI, +class CExtractCallbackImp Z7_final: + public IFolderArchiveExtractCallback, + /* IExtractCallbackUI: + before v23.00 : it included IFolderArchiveExtractCallback + since v23.00 : it doesn't include IFolderArchiveExtractCallback + */ + public IExtractCallbackUI, // NON-COM interface since 23.00 + public IOpenCallbackUI, // NON-COM interface public IFolderArchiveExtractCallback2, - #ifndef _SFX + #ifndef Z7_SFX public IFolderOperationsExtractCallback, public IFolderExtractToStreamCallback, public ICompressProgressInfo, - #endif - #ifndef _NO_CRYPTO + #endif + #ifndef Z7_NO_CRYPTO public ICryptoGetTextPassword, - #endif + #endif public CMyUnknownImp { - HRESULT MessageError(const char *message, const FString &path); - void Add_ArchiveName_Error(); -public: - MY_QUERYINTERFACE_BEGIN2(IFolderArchiveExtractCallback) - MY_QUERYINTERFACE_ENTRY(IFolderArchiveExtractCallback2) - #ifndef _SFX - MY_QUERYINTERFACE_ENTRY(IFolderOperationsExtractCallback) - MY_QUERYINTERFACE_ENTRY(IFolderExtractToStreamCallback) - MY_QUERYINTERFACE_ENTRY(ICompressProgressInfo) - #endif - #ifndef _NO_CRYPTO - MY_QUERYINTERFACE_ENTRY(ICryptoGetTextPassword) - #endif - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - INTERFACE_IProgress(;) - INTERFACE_IOpenCallbackUI(;) - INTERFACE_IFolderArchiveExtractCallback(;) - INTERFACE_IFolderArchiveExtractCallback2(;) - // STDMETHOD(SetTotalFiles)(UInt64 total); - // STDMETHOD(SetCompletedFiles)(const UInt64 *value); - - INTERFACE_IExtractCallbackUI(;) - - #ifndef _SFX - // IFolderOperationsExtractCallback - STDMETHOD(AskWrite)( - const wchar_t *srcPath, - Int32 srcIsFolder, - const FILETIME *srcTime, - const UInt64 *srcSize, - const wchar_t *destPathRequest, - BSTR *destPathResult, - Int32 *writeAnswer); - STDMETHOD(ShowMessage)(const wchar_t *message); - STDMETHOD(SetCurrentFilePath)(const wchar_t *filePath); - STDMETHOD(SetNumFiles)(UInt64 numFiles); - INTERFACE_IFolderExtractToStreamCallback(;) - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); - #endif + Z7_COM_QI_BEGIN2(IFolderArchiveExtractCallback) + Z7_COM_QI_ENTRY(IFolderArchiveExtractCallback2) + #ifndef Z7_SFX + Z7_COM_QI_ENTRY(IFolderOperationsExtractCallback) + Z7_COM_QI_ENTRY(IFolderExtractToStreamCallback) + Z7_COM_QI_ENTRY(ICompressProgressInfo) + #endif + #ifndef Z7_NO_CRYPTO + Z7_COM_QI_ENTRY(ICryptoGetTextPassword) + #endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_IMP(IExtractCallbackUI) + Z7_IFACE_IMP(IOpenCallbackUI) + Z7_IFACE_COM7_IMP(IProgress) + Z7_IFACE_COM7_IMP(IFolderArchiveExtractCallback) + Z7_IFACE_COM7_IMP(IFolderArchiveExtractCallback2) + #ifndef Z7_SFX + Z7_IFACE_COM7_IMP(IFolderOperationsExtractCallback) + Z7_IFACE_COM7_IMP(IFolderExtractToStreamCallback) + Z7_IFACE_COM7_IMP(ICompressProgressInfo) + #endif + #ifndef Z7_NO_CRYPTO + Z7_IFACE_COM7_IMP(ICryptoGetTextPassword) + #endif - // ICryptoGetTextPassword - #ifndef _NO_CRYPTO - STDMETHOD(CryptoGetTextPassword)(BSTR *password); - #endif -private: UString _currentArchivePath; bool _needWriteArchivePath; - UString _currentFilePath; bool _isFolder; + UString _currentFilePath; + UString _filePath; + #ifndef Z7_SFX + bool _needUpdateStat; + bool _newVirtFileWasAdded; bool _isAltStream; + bool _curSize_Defined; UInt64 _curSize; - bool _curSizeDefined; - UString _filePath; // bool _extractMode; // bool _testMode; - bool _newVirtFileWasAdded; - bool _needUpdateStat; - - - HRESULT SetCurrentFilePath2(const wchar_t *filePath); - void AddError_Message(LPCWSTR message); - - #ifndef _SFX bool _hashStreamWasUsed; COutStreamWithHash *_hashStreamSpec; CMyComPtr<ISequentialOutStream> _hashStream; IHashCalc *_hashCalc; // it's for stat in Test operation - #endif + #endif + + HRESULT SetCurrentFilePath2(const wchar_t *filePath); + void AddError_Message(LPCWSTR message); + HRESULT MessageError(const char *message, const FString &path); + void Add_ArchiveName_Error(); public: - #ifndef _SFX + #ifndef Z7_SFX CVirtFileSystem *VirtFileSystemSpec; CMyComPtr<ISequentialOutStream> VirtFileSystem; #endif @@ -263,7 +246,7 @@ public: bool StreamMode; CProgressDialog *ProgressDialog; - #ifndef _SFX + #ifndef Z7_SFX UInt64 NumFolders; UInt64 NumFiles; bool NeedAddFile; @@ -272,7 +255,7 @@ public: bool ThereAreMessageErrors; NExtract::NOverwriteMode::EEnum OverwriteMode; - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO bool PasswordIsDefined; bool PasswordWasAsked; UString Password; @@ -282,6 +265,7 @@ public: UString _lang_Extracting; UString _lang_Testing; UString _lang_Skipping; + UString _lang_Reading; UString _lang_Empty; bool _totalFilesDefined; @@ -289,27 +273,25 @@ public: bool MultiArcMode; CExtractCallbackImp(): - #ifndef _NO_CRYPTO + #ifndef Z7_SFX + _hashCalc(NULL), + #endif + ProcessAltStreams(true), + StreamMode(false), + OverwriteMode(NExtract::NOverwriteMode::kAsk), + #ifndef Z7_NO_CRYPTO PasswordIsDefined(false), PasswordWasAsked(false), #endif - OverwriteMode(NExtract::NOverwriteMode::kAsk), - StreamMode(false), - ProcessAltStreams(true), - _totalFilesDefined(false), _totalBytesDefined(false), MultiArcMode(false) - - #ifndef _SFX - , _hashCalc(NULL) - #endif {} ~CExtractCallbackImp(); void Init(); - #ifndef _SFX + #ifndef Z7_SFX void SetHashCalc(IHashCalc *hashCalc) { _hashCalc = hashCalc; } void SetHashMethods(IHashCalc *hash) diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/FormatUtils.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/FormatUtils.h index 993e803390f..1db08eff323 100644 --- a/3rdparty/lzma/CPP/7zip/UI/FileManager/FormatUtils.h +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/FormatUtils.h @@ -1,7 +1,7 @@ // FormatUtils.h -#ifndef __FORMAT_UTILS_H -#define __FORMAT_UTILS_H +#ifndef ZIP7_INC_FORMAT_UTILS_H +#define ZIP7_INC_FORMAT_UTILS_H #include "../../../Common/MyTypes.h" #include "../../../Common/MyString.h" diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/LangUtils.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/LangUtils.h index d63a443c6d3..d53d270eade 100644 --- a/3rdparty/lzma/CPP/7zip/UI/FileManager/LangUtils.h +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/LangUtils.h @@ -1,13 +1,16 @@ // LangUtils.h -#ifndef __LANG_UTILS_H -#define __LANG_UTILS_H +#ifndef ZIP7_INC_LANG_UTILS_H +#define ZIP7_INC_LANG_UTILS_H -#include "../../../Windows/ResourceString.h" +#include "../../../Common/Lang.h" -#ifdef LANG +#include "../../../Windows/ResourceString.h" extern UString g_LangID; +extern CLang g_Lang; + +#ifdef Z7_LANG struct CIDLangPair { @@ -17,11 +20,11 @@ struct CIDLangPair void ReloadLang(); void LoadLangOneTime(); -FString GetLangDirPrefix(); void LangSetDlgItemText(HWND dialog, UInt32 controlID, UInt32 langID); void LangSetDlgItems(HWND dialog, const UInt32 *ids, unsigned numItems); void LangSetDlgItems_Colon(HWND dialog, const UInt32 *ids, unsigned numItems); +void LangSetDlgItems_RemoveColon(HWND dialog, const UInt32 *ids, unsigned numItems); void LangSetWindowText(HWND window, UInt32 langID); UString LangString(UInt32 langID); @@ -37,4 +40,9 @@ inline void AddLangString(UString &s, UInt32 langID) { s += NWindows::MyLoadStri #endif +FString GetLangDirPrefix(); +// bool LangOpen(CLang &lang, CFSTR fileName); + +void Lang_GetShortNames_for_DefaultLang(AStringVector &names, unsigned &subLang); + #endif diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/MyWindowsNew.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/MyWindowsNew.h index 48a95359e6f..325babcd492 100644 --- a/3rdparty/lzma/CPP/7zip/UI/FileManager/MyWindowsNew.h +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/MyWindowsNew.h @@ -1,11 +1,54 @@ // MyWindowsNew.h -#ifndef __MY_WINDOWS_NEW_H -#define __MY_WINDOWS_NEW_H +#ifndef ZIP7_INC_MY_WINDOWS_NEW_H +#define ZIP7_INC_MY_WINDOWS_NEW_H -#ifdef _MSC_VER +#if defined(__MINGW32__) || defined(__MINGW64__) || defined(__MINGW32_VERSION) +#include <shobjidl.h> +#if defined(__MINGW32_VERSION) && !defined(__ITaskbarList3_INTERFACE_DEFINED__) +// for old mingw +extern "C" { +DEFINE_GUID(IID_ITaskbarList3, 0xEA1AFB91, 0x9E28, 0x4B86, 0x90, 0xE9, 0x9E, 0x9F, 0x8A, 0x5E, 0xEF, 0xAF); +DEFINE_GUID(CLSID_TaskbarList, 0x56fdf344, 0xfd6d, 0x11d0, 0x95,0x8a, 0x00,0x60,0x97,0xc9,0xa0,0x90); +} +#endif + +#else // is not __MINGW* + +#ifndef Z7_OLD_WIN_SDK #include <ShObjIdl.h> +#else + +#ifndef HIMAGELIST +struct _IMAGELIST; +typedef struct _IMAGELIST* HIMAGELIST; +#endif + +#ifndef __ITaskbarList_INTERFACE_DEFINED__ +#define __ITaskbarList_INTERFACE_DEFINED__ +DEFINE_GUID(IID_ITaskbarList, 0x56FDF342, 0xFD6D, 0x11d0, 0x95, 0x8A, 0x00, 0x60, 0x97, 0xC9, 0xA0, 0x90); +struct ITaskbarList: public IUnknown +{ + STDMETHOD(HrInit)(void) = 0; + STDMETHOD(AddTab)(HWND hwnd) = 0; + STDMETHOD(DeleteTab)(HWND hwnd) = 0; + STDMETHOD(ActivateTab)(HWND hwnd) = 0; + STDMETHOD(SetActiveAlt)(HWND hwnd) = 0; +}; +#endif // __ITaskbarList_INTERFACE_DEFINED__ + +#ifndef __ITaskbarList2_INTERFACE_DEFINED__ +#define __ITaskbarList2_INTERFACE_DEFINED__ +DEFINE_GUID(IID_ITaskbarList2, 0x602D4995, 0xB13A, 0x429b, 0xA6, 0x6E, 0x19, 0x35, 0xE4, 0x4F, 0x43, 0x17); +struct ITaskbarList2: public ITaskbarList +{ + STDMETHOD(MarkFullscreenWindow)(HWND hwnd, BOOL fFullscreen) = 0; +}; +#endif // __ITaskbarList2_INTERFACE_DEFINED__ + +#endif // Z7_OLD_WIN_SDK + #ifndef __ITaskbarList3_INTERFACE_DEFINED__ #define __ITaskbarList3_INTERFACE_DEFINED__ @@ -69,8 +112,8 @@ struct ITaskbarList3: public ITaskbarList2 STDMETHOD(SetThumbnailClip)(HWND hwnd, RECT *prcClip) = 0; }; -#endif +#endif // __ITaskbarList3_INTERFACE_DEFINED__ -#endif +#endif // __MINGW* #endif diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/OverwriteDialog.cpp b/3rdparty/lzma/CPP/7zip/UI/FileManager/OverwriteDialog.cpp index c6feb9021bb..096527ccf96 100644 --- a/3rdparty/lzma/CPP/7zip/UI/FileManager/OverwriteDialog.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/OverwriteDialog.cpp @@ -17,7 +17,7 @@ using namespace NWindows; -#ifdef LANG +#ifdef Z7_LANG static const UInt32 kLangIDs[] = { IDT_OVERWRITE_HEADER, @@ -40,9 +40,15 @@ void COverwriteDialog::ReduceString(UString &s) s.Delete(size / 2, s.Len() - size); s.Insert(size / 2, L" ... "); } + if (!s.IsEmpty() && s.Back() == ' ') + { + // s += (wchar_t)(0x2423); + s.InsertAtFront(L'\"'); + s += L'\"'; + } } -void COverwriteDialog::SetFileInfoControl(int textID, int iconID, +void COverwriteDialog::SetFileInfoControl(unsigned textID, unsigned iconID, const NOverwriteDialog::CFileInfo &fileInfo) { UString sizeString; @@ -51,8 +57,8 @@ void COverwriteDialog::SetFileInfoControl(int textID, int iconID, const UString &fileName = fileInfo.Name; int slashPos = fileName.ReverseFind_PathSepar(); - UString s1 = fileName.Left(slashPos + 1); - UString s2 = fileName.Ptr(slashPos + 1); + UString s1 = fileName.Left((unsigned)(slashPos + 1)); + UString s2 = fileName.Ptr((unsigned)(slashPos + 1)); ReduceString(s1); ReduceString(s2); @@ -66,13 +72,10 @@ void COverwriteDialog::SetFileInfoControl(int textID, int iconID, if (fileInfo.TimeIsDefined) { - FILETIME localFileTime; - if (!FileTimeToLocalFileTime(&fileInfo.Time, &localFileTime)) - throw 4190402; AddLangString(s, IDS_PROP_MTIME); - s += L": "; - wchar_t t[32]; - ConvertFileTimeToString(localFileTime, t); + s += ": "; + char t[32]; + ConvertUtcFileTimeToString(fileInfo.Time, t); s += t; } @@ -93,17 +96,33 @@ void COverwriteDialog::SetFileInfoControl(int textID, int iconID, bool COverwriteDialog::OnInit() { - #ifdef LANG + #ifdef Z7_LANG LangSetWindowText(*this, IDD_OVERWRITE); - LangSetDlgItems(*this, kLangIDs, ARRAY_SIZE(kLangIDs)); + LangSetDlgItems(*this, kLangIDs, Z7_ARRAY_SIZE(kLangIDs)); #endif SetFileInfoControl(IDT_OVERWRITE_OLD_FILE_SIZE_TIME, IDI_OVERWRITE_OLD_FILE, OldFileInfo); SetFileInfoControl(IDT_OVERWRITE_NEW_FILE_SIZE_TIME, IDI_OVERWRITE_NEW_FILE, NewFileInfo); NormalizePosition(); + + if (!ShowExtraButtons) + { + HideItem(IDB_YES_TO_ALL); + HideItem(IDB_NO_TO_ALL); + HideItem(IDB_AUTO_RENAME); + } + + if (DefaultButton_is_NO) + { + PostMsg(DM_SETDEFID, IDNO); + HWND h = GetItem(IDNO); + PostMsg(WM_NEXTDLGCTL, (WPARAM)h, TRUE); + // ::SetFocus(h); + } + return CModalDialog::OnInit(); } -bool COverwriteDialog::OnButtonClicked(int buttonID, HWND buttonHWND) +bool COverwriteDialog::OnButtonClicked(unsigned buttonID, HWND buttonHWND) { switch (buttonID) { @@ -112,7 +131,7 @@ bool COverwriteDialog::OnButtonClicked(int buttonID, HWND buttonHWND) case IDB_YES_TO_ALL: case IDB_NO_TO_ALL: case IDB_AUTO_RENAME: - End(buttonID); + End((INT_PTR)buttonID); return true; } return CModalDialog::OnButtonClicked(buttonID, buttonHWND); diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/OverwriteDialog.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/OverwriteDialog.h index da7fa55ff68..a9ca99158ee 100644 --- a/3rdparty/lzma/CPP/7zip/UI/FileManager/OverwriteDialog.h +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/OverwriteDialog.h @@ -1,7 +1,7 @@ // OverwriteDialog.h -#ifndef __OVERWRITE_DIALOG_H -#define __OVERWRITE_DIALOG_H +#ifndef ZIP7_INC_OVERWRITE_DIALOG_H +#define ZIP7_INC_OVERWRITE_DIALOG_H #include "../../../Windows/Control/Dialog.h" @@ -20,7 +20,7 @@ namespace NOverwriteDialog void SetTime(const FILETIME *t) { - if (t == 0) + if (!t) TimeIsDefined = false; else { @@ -28,15 +28,19 @@ namespace NOverwriteDialog Time = *t; } } + + void SetSize(UInt64 size) + { + SizeIsDefined = true; + Size = size; + } + void SetSize(const UInt64 *size) { - if (size == 0) + if (!size) SizeIsDefined = false; else - { - SizeIsDefined = true; - Size = *size; - } + SetSize(*size); } }; } @@ -45,13 +49,19 @@ class COverwriteDialog: public NWindows::NControl::CModalDialog { bool _isBig; - void SetFileInfoControl(int textID, int iconID, const NOverwriteDialog::CFileInfo &fileInfo); - virtual bool OnInit(); - bool OnButtonClicked(int buttonID, HWND buttonHWND); + void SetFileInfoControl(unsigned textID, unsigned iconID, const NOverwriteDialog::CFileInfo &fileInfo); + virtual bool OnInit() Z7_override; + virtual bool OnButtonClicked(unsigned buttonID, HWND buttonHWND) Z7_override; void ReduceString(UString &s); public: - INT_PTR Create(HWND parent = 0) + bool ShowExtraButtons; + bool DefaultButton_is_NO; + + + COverwriteDialog(): ShowExtraButtons(true), DefaultButton_is_NO(false) {} + + INT_PTR Create(HWND parent = NULL) { BIG_DIALOG_SIZE(280, 200); #ifdef UNDER_CE diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/PasswordDialog.cpp b/3rdparty/lzma/CPP/7zip/UI/FileManager/PasswordDialog.cpp index 6ead39c3764..bf995802aba 100644 --- a/3rdparty/lzma/CPP/7zip/UI/FileManager/PasswordDialog.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/PasswordDialog.cpp @@ -4,11 +4,11 @@ #include "PasswordDialog.h" -#ifdef LANG +#ifdef Z7_LANG #include "LangUtils.h" #endif -#ifdef LANG +#ifdef Z7_LANG static const UInt32 kLangIDs[] = { IDT_PASSWORD_ENTER, @@ -30,9 +30,9 @@ void CPasswordDialog::SetTextSpec() bool CPasswordDialog::OnInit() { - #ifdef LANG + #ifdef Z7_LANG LangSetWindowText(*this, IDD_PASSWORD); - LangSetDlgItems(*this, kLangIDs, ARRAY_SIZE(kLangIDs)); + LangSetDlgItems(*this, kLangIDs, Z7_ARRAY_SIZE(kLangIDs)); #endif _passwordEdit.Attach(GetItem(IDE_PASSWORD_PASSWORD)); CheckButton(IDX_PASSWORD_SHOW, ShowPassword); @@ -40,7 +40,7 @@ bool CPasswordDialog::OnInit() return CModalDialog::OnInit(); } -bool CPasswordDialog::OnButtonClicked(int buttonID, HWND buttonHWND) +bool CPasswordDialog::OnButtonClicked(unsigned buttonID, HWND buttonHWND) { if (buttonID == IDX_PASSWORD_SHOW) { diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/PasswordDialog.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/PasswordDialog.h index 339ebdaf072..e05c4adf7e5 100644 --- a/3rdparty/lzma/CPP/7zip/UI/FileManager/PasswordDialog.h +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/PasswordDialog.h @@ -1,7 +1,7 @@ // PasswordDialog.h -#ifndef __PASSWORD_DIALOG_H -#define __PASSWORD_DIALOG_H +#ifndef ZIP7_INC_PASSWORD_DIALOG_H +#define ZIP7_INC_PASSWORD_DIALOG_H #include "../../../Windows/Control/Dialog.h" #include "../../../Windows/Control/Edit.h" @@ -12,9 +12,9 @@ class CPasswordDialog: public NWindows::NControl::CModalDialog { NWindows::NControl::CEdit _passwordEdit; - virtual void OnOK(); - virtual bool OnInit(); - virtual bool OnButtonClicked(int buttonID, HWND buttonHWND); + virtual void OnOK() Z7_override; + virtual bool OnInit() Z7_override; + virtual bool OnButtonClicked(unsigned buttonID, HWND buttonHWND) Z7_override; void SetTextSpec(); void ReadControls(); public: @@ -22,7 +22,7 @@ public: bool ShowPassword; CPasswordDialog(): ShowPassword(false) {} - INT_PTR Create(HWND parentWindow = 0) { return CModalDialog::Create(IDD_PASSWORD, parentWindow); } + INT_PTR Create(HWND parentWindow = NULL) { return CModalDialog::Create(IDD_PASSWORD, parentWindow); } }; #endif diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog.cpp b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog.cpp index 65201a9ed16..fc6f559923f 100644 --- a/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog.cpp @@ -15,7 +15,7 @@ extern HINSTANCE g_hInstance; static const UINT_PTR kTimerID = 3; static const UINT kTimerElapse = 100; -#ifdef LANG +#ifdef Z7_LANG #include "LangUtils.h" #endif @@ -32,7 +32,7 @@ HRESULT CProgressSync::ProcessStopAndPause() return S_OK; } -#ifndef _SFX +#ifndef Z7_SFX CProgressDialog::~CProgressDialog() { AddToTitle(L""); @@ -45,15 +45,17 @@ void CProgressDialog::AddToTitle(LPCWSTR s) #endif +#define UNDEFINED_VAL ((UInt64)(Int64)-1) + bool CProgressDialog::OnInit() { - _range = (UInt64)(Int64)-1; - _prevPercentValue = -1; + _range = UNDEFINED_VAL; + _prevPercentValue = UNDEFINED_VAL; _wasCreated = true; _dialogCreatedEvent.Set(); - #ifdef LANG + #ifdef Z7_LANG LangSetDlgItems(*this, NULL, 0); #endif @@ -114,15 +116,15 @@ bool CProgressDialog::OnTimer(WPARAM /* timerID */, LPARAM /* callback */) if (total == 0) total = 1; - int percentValue = (int)(completed * 100 / total); + const UInt64 percentValue = completed * 100 / total; if (percentValue != _prevPercentValue) { wchar_t s[64]; ConvertUInt64ToString(percentValue, s); UString title = s; - title += L"% "; + title += "% "; SetText(title + _title); - #ifndef _SFX + #ifndef Z7_SFX AddToTitle(title + MainAddTitle); #endif _prevPercentValue = percentValue; @@ -136,8 +138,11 @@ bool CProgressDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) { case kCloseMessage: { - KillTimer(_timer); - _timer = 0; + if (_timer) + { + KillTimer(kTimerID); + _timer = 0; + } if (_inCancelMessageBox) { _externalCloseMessageWasReceived = true; @@ -156,7 +161,7 @@ bool CProgressDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) return CModalDialog::OnMessage(message, wParam, lParam); } -bool CProgressDialog::OnButtonClicked(int buttonID, HWND buttonHWND) +bool CProgressDialog::OnButtonClicked(unsigned buttonID, HWND buttonHWND) { switch (buttonID) { diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog.h index 0f41b57aed6..1fe9587a541 100644 --- a/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog.h +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog.h @@ -1,7 +1,7 @@ // ProgressDialog.h -#ifndef __PROGRESS_DIALOG_H -#define __PROGRESS_DIALOG_H +#ifndef ZIP7_INC_PROGRESS_DIALOG_H +#define ZIP7_INC_PROGRESS_DIALOG_H #include "../../../Windows/Synchronization.h" #include "../../../Windows/Thread.h" @@ -85,24 +85,27 @@ private: UInt64 _range; NWindows::NControl::CProgressBar m_ProgressBar; - int _prevPercentValue; + UInt64 _prevPercentValue; bool _wasCreated; bool _needClose; bool _inCancelMessageBox; bool _externalCloseMessageWasReceived; - bool OnTimer(WPARAM timerID, LPARAM callback); + virtual bool OnButtonClicked(unsigned buttonID, HWND buttonHWND) Z7_override; + virtual bool OnTimer(WPARAM timerID, LPARAM callback) Z7_override; + virtual bool OnInit() Z7_override; + virtual void OnCancel() Z7_override; + virtual void OnOK() Z7_override; + virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam) Z7_override; + void SetRange(UInt64 range); void SetPos(UInt64 pos); - virtual bool OnInit(); - virtual void OnCancel(); - virtual void OnOK(); + NWindows::NSynchronization::CManualResetEvent _dialogCreatedEvent; - #ifndef _SFX + #ifndef Z7_SFX void AddToTitle(LPCWSTR string); #endif - bool OnButtonClicked(int buttonID, HWND buttonHWND); void WaitCreating() { _dialogCreatedEvent.Lock(); } void CheckNeedClose(); @@ -111,7 +114,7 @@ public: CProgressSync Sync; int IconID; - #ifndef _SFX + #ifndef Z7_SFX HWND MainWindow; UString MainTitle; UString MainAddTitle; @@ -119,8 +122,8 @@ public: #endif CProgressDialog(): _timer(0) - #ifndef _SFX - ,MainWindow(0) + #ifndef Z7_SFX + ,MainWindow(NULL) #endif { IconID = -1; @@ -133,11 +136,11 @@ public: throw 1334987; } - INT_PTR Create(const UString &title, NWindows::CThread &thread, HWND wndParent = 0) + INT_PTR Create(const UString &title, NWindows::CThread &thread, HWND wndParent = NULL) { _title = title; INT_PTR res = CModalDialog::Create(IDD_PROGRESS, wndParent); - thread.Wait(); + thread.Wait_Close(); return res; } @@ -146,8 +149,6 @@ public: kCloseMessage = WM_APP + 1 }; - virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam); - void ProcessWasFinished() { WaitCreating(); @@ -155,7 +156,7 @@ public: PostMsg(kCloseMessage); else _needClose = true; - }; + } }; diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2.cpp b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2.cpp index 8c38b81aa0a..1521d83ceca 100644 --- a/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2.cpp @@ -2,10 +2,14 @@ #include "StdAfx.h" +#ifdef Z7_OLD_WIN_SDK +#include <ShlGuid.h> +#endif + #include "../../../Common/IntToString.h" #include "../../../Common/StringConvert.h" -#include "../../../Windows/Control/Static.h" +#include "../../../Windows/Clipboard.h" #include "../../../Windows/ErrorMsg.h" #include "../GUI/ExtractRes.h" @@ -43,7 +47,7 @@ static const UINT kCreateDelay = static const DWORD kPauseSleepTime = 100; -#ifdef LANG +#ifdef Z7_LANG static const UInt32 kLangIDs[] = { @@ -67,19 +71,19 @@ static const UInt32 kLangIDs_Colon[] = #endif -#define UNDEFINED_VAL ((UInt64)(Int64)-1) -#define INIT_AS_UNDEFINED(v) v = UNDEFINED_VAL; -#define IS_UNDEFINED_VAL(v) ((v) == UNDEFINED_VAL) -#define IS_DEFINED_VAL(v) ((v) != UNDEFINED_VAL) +#define UNDEFINED_VAL ((UInt64)(Int64)-1) +#define INIT_AS_UNDEFINED(v) v = UNDEFINED_VAL; +#define IS_UNDEFINED_VAL(v) ((v) == UNDEFINED_VAL) +#define IS_DEFINED_VAL(v) ((v) != UNDEFINED_VAL) CProgressSync::CProgressSync(): _stopped(false), _paused(false), _bytesProgressMode(true), + _isDir(false), _totalBytes(UNDEFINED_VAL), _completedBytes(0), _totalFiles(UNDEFINED_VAL), _curFiles(0), _inSize(UNDEFINED_VAL), - _outSize(UNDEFINED_VAL), - _isDir(false) + _outSize(UNDEFINED_VAL) {} #define CHECK_STOP if (_stopped) return E_ABORT; if (!_paused) return S_OK; @@ -217,7 +221,7 @@ void CProgressSync::AddError_Message_Name(const wchar_t *message, const wchar_t UString s; if (name && *name != 0) s += name; - if (message && *message != 0 ) + if (message && *message != 0) { if (!s.IsEmpty()) s.Add_LF(); @@ -228,15 +232,18 @@ void CProgressSync::AddError_Message_Name(const wchar_t *message, const wchar_t AddError_Message(s); } -void CProgressSync::AddError_Code_Name(DWORD systemError, const wchar_t *name) +void CProgressSync::AddError_Code_Name(HRESULT systemError, const wchar_t *name) { UString s = NError::MyFormatMessage(systemError); if (systemError == 0) - s = L"Error"; + s = "Error"; AddError_Message_Name(s, name); } -CProgressDialog::CProgressDialog(): _timer(0), CompressingMode(true), MainWindow(0) +CProgressDialog::CProgressDialog(): + _timer(0), + CompressingMode(true), + MainWindow(NULL) { _isDir = false; @@ -259,25 +266,25 @@ CProgressDialog::CProgressDialog(): _timer(0), CompressingMode(true), MainWindow throw 1334987; if (_createDialogEvent.Create() != S_OK) throw 1334987; - #ifdef __ITaskbarList3_INTERFACE_DEFINED__ + // #ifdef __ITaskbarList3_INTERFACE_DEFINED__ CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_ITaskbarList3, (void**)&_taskbarList); if (_taskbarList) _taskbarList->HrInit(); - #endif + // #endif } -#ifndef _SFX +#ifndef Z7_SFX CProgressDialog::~CProgressDialog() { - #ifdef __ITaskbarList3_INTERFACE_DEFINED__ + // #ifdef __ITaskbarList3_INTERFACE_DEFINED__ SetTaskbarProgressState(TBPF_NOPROGRESS); - #endif + // #endif AddToTitle(L""); } void CProgressDialog::AddToTitle(LPCWSTR s) { - if (MainWindow != 0) + if (MainWindow) { CWindow window(MainWindow); window.SetText((UString)s + MainTitle); @@ -289,7 +296,7 @@ void CProgressDialog::AddToTitle(LPCWSTR s) void CProgressDialog::SetTaskbarProgressState() { - #ifdef __ITaskbarList3_INTERFACE_DEFINED__ + // #ifdef __ITaskbarList3_INTERFACE_DEFINED__ if (_taskbarList && _hwndForTaskbar) { TBPFLAG tbpFlags; @@ -299,7 +306,7 @@ void CProgressDialog::SetTaskbarProgressState() tbpFlags = _errorsWereDisplayed ? TBPF_ERROR: TBPF_NORMAL; SetTaskbarProgressState(tbpFlags); } - #endif + // #endif } static const unsigned kTitleFileNameSizeLimit = 36; @@ -328,37 +335,40 @@ bool CProgressDialog::OnInit() if (!_hwndForTaskbar) _hwndForTaskbar = *this; - INIT_AS_UNDEFINED(_progressBar_Range); - INIT_AS_UNDEFINED(_progressBar_Pos); + INIT_AS_UNDEFINED(_progressBar_Range) + INIT_AS_UNDEFINED(_progressBar_Pos) - INIT_AS_UNDEFINED(_prevPercentValue); - INIT_AS_UNDEFINED(_prevElapsedSec); - INIT_AS_UNDEFINED(_prevRemainingSec); + INIT_AS_UNDEFINED(_prevPercentValue) + INIT_AS_UNDEFINED(_prevElapsedSec) + INIT_AS_UNDEFINED(_prevRemainingSec) - INIT_AS_UNDEFINED(_prevSpeed); + INIT_AS_UNDEFINED(_prevSpeed) _prevSpeed_MoveBits = 0; _prevTime = ::GetTickCount(); _elapsedTime = 0; - INIT_AS_UNDEFINED(_totalBytes_Prev); - INIT_AS_UNDEFINED(_processed_Prev); - INIT_AS_UNDEFINED(_packed_Prev); - INIT_AS_UNDEFINED(_ratio_Prev); + INIT_AS_UNDEFINED(_totalBytes_Prev) + INIT_AS_UNDEFINED(_processed_Prev) + INIT_AS_UNDEFINED(_packed_Prev) + INIT_AS_UNDEFINED(_ratio_Prev) + _filesStr_Prev.Empty(); + _filesTotStr_Prev.Empty(); _foreground = true; m_ProgressBar.Attach(GetItem(IDC_PROGRESS1)); _messageList.Attach(GetItem(IDL_PROGRESS_MESSAGES)); _messageList.SetUnicodeFormat(); + _messageList.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT); _wasCreated = true; _dialogCreatedEvent.Set(); - #ifdef LANG - LangSetDlgItems(*this, kLangIDs, ARRAY_SIZE(kLangIDs)); - LangSetDlgItems_Colon(*this, kLangIDs_Colon, ARRAY_SIZE(kLangIDs_Colon)); + #ifdef Z7_LANG + LangSetDlgItems(*this, kLangIDs, Z7_ARRAY_SIZE(kLangIDs)); + LangSetDlgItems_Colon(*this, kLangIDs_Colon, Z7_ARRAY_SIZE(kLangIDs_Colon)); #endif CWindow window(GetItem(IDB_PROGRESS_BACKGROUND)); @@ -420,13 +430,14 @@ static const UINT kIDs[] = IDT_PROGRESS_ELAPSED, IDT_PROGRESS_ELAPSED_VAL, IDT_PROGRESS_REMAINING, IDT_PROGRESS_REMAINING_VAL, IDT_PROGRESS_FILES, IDT_PROGRESS_FILES_VAL, - IDT_PROGRESS_RATIO, IDT_PROGRESS_RATIO_VAL, + 0, IDT_PROGRESS_FILES_TOTAL, IDT_PROGRESS_ERRORS, IDT_PROGRESS_ERRORS_VAL, IDT_PROGRESS_TOTAL, IDT_PROGRESS_TOTAL_VAL, IDT_PROGRESS_SPEED, IDT_PROGRESS_SPEED_VAL, IDT_PROGRESS_PROCESSED, IDT_PROGRESS_PROCESSED_VAL, - IDT_PROGRESS_PACKED, IDT_PROGRESS_PACKED_VAL + IDT_PROGRESS_PACKED, IDT_PROGRESS_PACKED_VAL, + IDT_PROGRESS_RATIO, IDT_PROGRESS_RATIO_VAL }; bool CProgressDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize) @@ -446,12 +457,12 @@ bool CProgressDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize) InvalidateRect(NULL); - int xSizeClient = xSize - mx * 2; + const int xSizeClient = xSize - mx * 2; { - int i; + unsigned i; for (i = 800; i > 40; i = i * 9 / 10) - if (Units_To_Pixels_X(i) <= xSizeClient) + if (Units_To_Pixels_X((int)i) <= xSizeClient) break; _numReduceSymbols = i / 4; } @@ -466,7 +477,7 @@ bool CProgressDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize) int mx2 = mx; for (;; mx2--) { - int bSize2 = bSizeX * 3 + mx2 * 2; + const int bSize2 = bSizeX * 3 + mx2 * 2; if (bSize2 <= xSizeClient) break; if (mx2 < 5) @@ -481,7 +492,7 @@ bool CProgressDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize) { RECT r; GetClientRectOfItem(IDL_PROGRESS_MESSAGES, r); - int y = r.top; + const int y = r.top; int ySize2 = yPos - my - y; const int kMinYSize = _buttonSizeY + _buttonSizeY * 3 / 4; int xx = xSize - mx * 2; @@ -512,13 +523,13 @@ bool CProgressDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize) labelSize = Units_To_Pixels_X(MY_PROGRESS_LABEL_UNITS_MIN); valueSize = Units_To_Pixels_X(MY_PROGRESS_VAL_UNITS); padSize = Units_To_Pixels_X(MY_PROGRESS_PAD_UNITS); - int requiredSize = (labelSize + valueSize) * 2 + padSize; + const int requiredSize = (labelSize + valueSize) * 2 + padSize; int gSize; { if (requiredSize < xSizeClient) { - int incr = (xSizeClient - requiredSize) / 3; + const int incr = (xSizeClient - requiredSize) / 3; labelSize += incr; } else @@ -533,16 +544,17 @@ bool CProgressDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize) labelSize = gSize - valueSize; yPos = my; - for (int i = 0; i < ARRAY_SIZE(kIDs); i += 2) + for (unsigned i = 0; i < Z7_ARRAY_SIZE(kIDs); i += 2) { int x = mx; - const int kNumColumn1Items = 5 * 2; + const unsigned kNumColumn1Items = 5 * 2; if (i >= kNumColumn1Items) { if (i == kNumColumn1Items) yPos = my; x = mx + gSize + padSize; } + if (kIDs[i] != 0) MoveItem(kIDs[i], x, yPos, labelSize, sY); MoveItem(kIDs[i + 1], x + labelSize, yPos, valueSize, sY); yPos += sStep; @@ -558,7 +570,7 @@ void CProgressDialog::SetProgressRange(UInt64 range) if (range == _progressBar_Range) return; _progressBar_Range = range; - INIT_AS_UNDEFINED(_progressBar_Pos); + INIT_AS_UNDEFINED(_progressBar_Pos) _progressConv.Init(range); m_ProgressBar.SetRange32(0, _progressConv.Count(range)); } @@ -570,16 +582,17 @@ void CProgressDialog::SetProgressPos(UInt64 pos) pos - _progressBar_Pos >= (_progressBar_Range >> 10)) { m_ProgressBar.SetPos(_progressConv.Count(pos)); - #ifdef __ITaskbarList3_INTERFACE_DEFINED__ + // #ifdef __ITaskbarList3_INTERFACE_DEFINED__ if (_taskbarList && _hwndForTaskbar) _taskbarList->SetProgressValue(_hwndForTaskbar, pos, _progressBar_Range); - #endif + // #endif _progressBar_Pos = pos; } } #define UINT_TO_STR_2(val) { s[0] = (wchar_t)('0' + (val) / 10); s[1] = (wchar_t)('0' + (val) % 10); s += 2; } +void GetTimeString(UInt64 timeValue, wchar_t *s); void GetTimeString(UInt64 timeValue, wchar_t *s) { UInt64 hours = timeValue / 3600; @@ -594,10 +607,10 @@ void GetTimeString(UInt64 timeValue, wchar_t *s) else { UInt32 hours32 = (UInt32)hours; - UINT_TO_STR_2(hours32); + UINT_TO_STR_2(hours32) } - *s++ = ':'; UINT_TO_STR_2(minutes); - *s++ = ':'; UINT_TO_STR_2(seconds); + *s++ = ':'; UINT_TO_STR_2(minutes) + *s++ = ':'; UINT_TO_STR_2(seconds) *s = 0; } @@ -613,11 +626,12 @@ static void ConvertSizeToString(UInt64 v, wchar_t *s) s += MyStringLen(s); *s++ = ' '; *s++ = c; + *s++ = 'B'; *s++ = 0; } } -void CProgressDialog::ShowSize(int id, UInt64 val, UInt64 &prev) +void CProgressDialog::ShowSize(unsigned id, UInt64 val, UInt64 &prev) { if (val == prev) return; @@ -761,7 +775,7 @@ void CProgressDialog::UpdateStatInfo(bool showAll) { if (IS_DEFINED_VAL(_prevRemainingSec)) { - INIT_AS_UNDEFINED(_prevRemainingSec); + INIT_AS_UNDEFINED(_prevRemainingSec) SetItemText(IDT_PROGRESS_REMAINING_VAL, L""); } } @@ -780,8 +794,9 @@ void CProgressDialog::UpdateStatInfo(bool showAll) } } { - UInt64 elapsedTime = (_elapsedTime == 0) ? 1 : _elapsedTime; - UInt64 v = (progressCompleted * 1000) / elapsedTime; + const UInt64 elapsedTime = (_elapsedTime == 0) ? 1 : _elapsedTime; + // 22.02: progressCompleted can be for number of files + UInt64 v = (completed * 1000) / elapsedTime; Byte c = 0; unsigned moveBits = 0; if (v >= ((UInt64)10000 << 10)) { moveBits = 20; c = 'M'; } @@ -825,17 +840,25 @@ void CProgressDialog::UpdateStatInfo(bool showAll) { wchar_t s[64]; + ConvertUInt64ToString(completedFiles, s); - if (IS_DEFINED_VAL(totalFiles)) - { - wcscat(s, L" / "); - ConvertUInt64ToString(totalFiles, s + wcslen(s)); - } if (_filesStr_Prev != s) { _filesStr_Prev = s; SetItemText(IDT_PROGRESS_FILES_VAL, s); } + + s[0] = 0; + if (IS_DEFINED_VAL(totalFiles)) + { + MyStringCopy(s, L" / "); + ConvertUInt64ToString(totalFiles, s + MyStringLen(s)); + } + if (_filesTotStr_Prev != s) + { + _filesTotStr_Prev = s; + SetItemText(IDT_PROGRESS_FILES_TOTAL, s); + } } const UInt64 packSize = CompressingMode ? outSize : inSize; @@ -862,7 +885,7 @@ void CProgressDialog::UpdateStatInfo(bool showAll) { _ratio_Prev = ratio; ConvertUInt64ToString(ratio, s); - wcscat(s, L"%"); + MyStringCat(s, L"%"); SetItemText(IDT_PROGRESS_RATIO_VAL, s); } } @@ -889,8 +912,8 @@ void CProgressDialog::UpdateStatInfo(bool showAll) int slashPos = _filePath.ReverseFind_PathSepar(); if (slashPos >= 0) { - s1.SetFrom(_filePath, slashPos + 1); - s2 = _filePath.Ptr(slashPos + 1); + s1.SetFrom(_filePath, (unsigned)(slashPos + 1)); + s2 = _filePath.Ptr((unsigned)(slashPos + 1)); } else s2 = _filePath; @@ -939,7 +962,7 @@ INT_PTR CProgressDialog::Create(const UString &title, NWindows::CThread &thread, CWaitCursor waitCursor; HANDLE h[] = { thread, _createDialogEvent }; - WRes res2 = WaitForMultipleObjects(ARRAY_SIZE(h), h, FALSE, kCreateDelay); + const DWORD res2 = WaitForMultipleObjects(Z7_ARRAY_SIZE(h), h, FALSE, kCreateDelay); if (res2 == WAIT_OBJECT_0 && !Sync.ThereIsMessage()) return 0; } @@ -951,9 +974,8 @@ INT_PTR CProgressDialog::Create(const UString &title, NWindows::CThread &thread, { _wasCreated = true; _dialogCreatedEvent.Set(); - res = res; } - thread.Wait(); + thread.Wait_Close(); if (!MessagesDisplayed) MessageBoxW(wndParent, L"Progress Error", L"7-Zip", MB_ICONERROR); return res; @@ -962,9 +984,9 @@ INT_PTR CProgressDialog::Create(const UString &title, NWindows::CThread &thread, bool CProgressDialog::OnExternalCloseMessage() { // it doesn't work if there is MessageBox. - #ifdef __ITaskbarList3_INTERFACE_DEFINED__ + // #ifdef __ITaskbarList3_INTERFACE_DEFINED__ SetTaskbarProgressState(TBPF_NOPROGRESS); - #endif + // #endif // AddToTitle(L"Finished "); // SetText(L"Finished2 "); @@ -974,7 +996,9 @@ bool CProgressDialog::OnExternalCloseMessage() ::SendMessage(GetItem(IDCANCEL), BM_SETSTYLE, BS_DEFPUSHBUTTON, MAKELPARAM(TRUE, 0)); HideItem(IDB_PROGRESS_BACKGROUND); HideItem(IDB_PAUSE); - + + ProcessWasFinished_GuiVirt(); + bool thereAreMessages; CProgressFinalMessage fm; { @@ -982,20 +1006,22 @@ bool CProgressDialog::OnExternalCloseMessage() thereAreMessages = !Sync.Messages.IsEmpty(); fm = Sync.FinalMessage; } + if (!fm.ErrorMessage.Message.IsEmpty()) { MessagesDisplayed = true; if (fm.ErrorMessage.Title.IsEmpty()) - fm.ErrorMessage.Title = L"7-Zip"; + fm.ErrorMessage.Title = "7-Zip"; MessageBoxW(*this, fm.ErrorMessage.Message, fm.ErrorMessage.Title, MB_ICONERROR); } else if (!thereAreMessages) { MessagesDisplayed = true; + if (!fm.OkMessage.Message.IsEmpty()) { if (fm.OkMessage.Title.IsEmpty()) - fm.OkMessage.Title = L"7-Zip"; + fm.OkMessage.Title = "7-Zip"; MessageBoxW(*this, fm.OkMessage.Message, fm.OkMessage.Title, MB_OK); } } @@ -1017,10 +1043,17 @@ bool CProgressDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) { case kCloseMessage: { - KillTimer(_timer); - _timer = 0; + if (_timer) + { + /* 21.03 : KillTimer(kTimerID) instead of KillTimer(_timer). + But (_timer == kTimerID) in Win10. So it worked too */ + KillTimer(kTimerID); + _timer = 0; + } if (_inCancelMessageBox) { + /* if user is in MessageBox(), we will call OnExternalCloseMessage() + later, when MessageBox() will be closed */ _externalCloseMessageWasReceived = true; break; } @@ -1050,8 +1083,8 @@ void CProgressDialog::SetTitleText() { char temp[32]; ConvertUInt64ToString(_prevPercentValue, temp); - s.AddAscii(temp); - s += L'%'; + s += temp; + s += '%'; } if (!_foreground) { @@ -1060,7 +1093,7 @@ void CProgressDialog::SetTitleText() } s.Add_Space(); - #ifndef _SFX + #ifndef Z7_SFX { unsigned len = s.Len(); s += MainAddTitle; @@ -1117,13 +1150,16 @@ void CProgressDialog::OnPriorityButton() void CProgressDialog::AddMessageDirect(LPCWSTR message, bool needNumber) { - int itemIndex = _messageList.GetItemCount(); wchar_t sz[16]; sz[0] = 0; if (needNumber) ConvertUInt32ToString(_numMessages + 1, sz); - _messageList.InsertItem(itemIndex, sz); - _messageList.SetSubItem(itemIndex, 1, message); + const unsigned itemIndex = _messageStrings.Size(); // _messageList.GetItemCount(); + if (_messageList.InsertItem(itemIndex, sz) == (int)itemIndex) + { + _messageList.SetSubItem(itemIndex, 1, message); + _messageStrings.Add(message); + } } void CProgressDialog::AddMessage(LPCWSTR message) @@ -1132,12 +1168,12 @@ void CProgressDialog::AddMessage(LPCWSTR message) bool needNumber = true; while (!s.IsEmpty()) { - int pos = s.Find(L'\n'); + const int pos = s.Find(L'\n'); if (pos < 0) break; - AddMessageDirect(s.Left(pos), needNumber); + AddMessageDirect(s.Left((unsigned)pos), needNumber); needNumber = false; - s.DeleteFrontal(pos + 1); + s.DeleteFrontal((unsigned)pos + 1); } AddMessageDirect(s, needNumber); _numMessages++; @@ -1179,7 +1215,7 @@ void CProgressDialog::UpdateMessagesDialog() } -bool CProgressDialog::OnButtonClicked(int buttonID, HWND buttonHWND) +bool CProgressDialog::OnButtonClicked(unsigned buttonID, HWND buttonHWND) { switch (buttonID) { @@ -1192,24 +1228,42 @@ bool CProgressDialog::OnButtonClicked(int buttonID, HWND buttonHWND) End(IDCLOSE); break; } + + if (_cancelWasPressed) + return true; - bool paused = Sync.Get_Paused(); + const bool paused = Sync.Get_Paused(); + if (!paused) + { OnPauseButton(); + } + _inCancelMessageBox = true; - int res = ::MessageBoxW(*this, LangString(IDS_PROGRESS_ASK_CANCEL), _title, MB_YESNOCANCEL); + const int res = ::MessageBoxW(*this, LangString(IDS_PROGRESS_ASK_CANCEL), _title, MB_YESNOCANCEL); _inCancelMessageBox = false; + if (res == IDYES) + _cancelWasPressed = true; + if (!paused) + { OnPauseButton(); - if (res == IDCANCEL || res == IDNO) + } + + if (_externalCloseMessageWasReceived) { - if (_externalCloseMessageWasReceived) - OnExternalCloseMessage(); + /* we have received kCloseMessage while we were in MessageBoxW(). + so we call OnExternalCloseMessage() here. + it can show MessageBox and it can close dialog */ + OnExternalCloseMessage(); return true; } - _cancelWasPressed = true; + if (!_cancelWasPressed) + return true; + MessagesDisplayed = true; + // we will call Sync.Set_Stopped(true) in OnButtonClicked() : OnCancel() break; } @@ -1245,11 +1299,107 @@ void CProgressDialog::ProcessWasFinished() } +bool CProgressDialog::OnNotify(UINT /* controlID */, LPNMHDR header) +{ + if (header->hwndFrom != _messageList) + return false; + switch (header->code) + { + case LVN_KEYDOWN: + { + LPNMLVKEYDOWN keyDownInfo = LPNMLVKEYDOWN(header); + switch (keyDownInfo->wVKey) + { + case 'A': + { + if (IsKeyDown(VK_CONTROL)) + { + _messageList.SelectAll(); + return true; + } + break; + } + case VK_INSERT: + case 'C': + { + if (IsKeyDown(VK_CONTROL)) + { + CopyToClipboard(); + return true; + } + break; + } + } + } + } + return false; +} + + +static void ListView_GetSelected(NControl::CListView &listView, CUIntVector &vector) +{ + vector.Clear(); + int index = -1; + for (;;) + { + index = listView.GetNextSelectedItem(index); + if (index < 0) + break; + vector.Add((unsigned)index); + } +} + + +void CProgressDialog::CopyToClipboard() +{ + CUIntVector indexes; + ListView_GetSelected(_messageList, indexes); + UString s; + unsigned numIndexes = indexes.Size(); + if (numIndexes == 0) + numIndexes = (unsigned)_messageList.GetItemCount(); + + for (unsigned i = 0; i < numIndexes; i++) + { + const unsigned index = (i < indexes.Size() ? indexes[i] : i); + // s.Add_UInt32(index); + // s += ": "; + s += _messageStrings[index]; + { + s += + #ifdef _WIN32 + "\r\n" + #else + "\n" + #endif + ; + } + } + + ClipboardSetText(*this, s); +} + + +static THREAD_FUNC_DECL MyThreadFunction(void *param) +{ + CProgressThreadVirt *p = (CProgressThreadVirt *)param; + try + { + p->Process(); + p->ThreadFinishedOK = true; + } + catch (...) { p->Result = E_FAIL; } + return 0; +} + + HRESULT CProgressThreadVirt::Create(const UString &title, HWND parentWindow) { NWindows::CThread thread; - RINOK(thread.Create(MyThreadFunction, this)); - ProgressDialog.Create(title, thread, parentWindow); + const WRes wres = thread.Create(MyThreadFunction, this); + if (wres != 0) + return HRESULT_FROM_WIN32(wres); + CProgressDialog::Create(title, thread, parentWindow); return S_OK; } @@ -1265,7 +1415,7 @@ static void AddMessageToString(UString &dest, const UString &src) void CProgressThreadVirt::Process() { - CProgressCloser closer(ProgressDialog); + CProgressCloser closer(*this); UString m; try { Result = ProcessVirt(); } catch(const wchar_t *s) { m = s; } @@ -1273,12 +1423,10 @@ void CProgressThreadVirt::Process() catch(const char *s) { m = GetUnicodeString(s); } catch(int v) { - wchar_t s[16]; - ConvertUInt32ToString(v, s); - m = L"Error #"; - m += s; + m = "Error #"; + m.Add_UInt32((unsigned)v); } - catch(...) { m = L"Error"; } + catch(...) { m = "Error"; } if (Result != E_ABORT) { if (m.IsEmpty() && Result != S_OK) @@ -1295,7 +1443,7 @@ void CProgressThreadVirt::Process() } } - CProgressSync &sync = ProgressDialog.Sync; + CProgressSync &sync = Sync; NSynchronization::CCriticalSectionLock lock(sync._cs); if (m.IsEmpty()) { diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2.h index 03f836da219..4ca9be7a40c 100644 --- a/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2.h +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2.h @@ -1,7 +1,7 @@ // ProgressDialog2.h -#ifndef __PROGRESS_DIALOG_2_H -#define __PROGRESS_DIALOG_2_H +#ifndef ZIP7_INC_PROGRESS_DIALOG_2_H +#define ZIP7_INC_PROGRESS_DIALOG_2_H #include "../../../Common/MyCom.h" @@ -36,6 +36,7 @@ class CProgressSync public: bool _bytesProgressMode; + bool _isDir; UInt64 _totalBytes; UInt64 _completedBytes; UInt64 _totalFiles; @@ -46,7 +47,6 @@ public: UString _titleFileName; UString _status; UString _filePath; - bool _isDir; UStringVector Messages; CProgressFinalMessage FinalMessage; @@ -96,7 +96,8 @@ public: void AddError_Message(const wchar_t *message); void AddError_Message_Name(const wchar_t *message, const wchar_t *name); - void AddError_Code_Name(DWORD systemError, const wchar_t *name); + // void AddError_Code_Name(DWORD systemError, const wchar_t *name); + void AddError_Code_Name(HRESULT systemError, const wchar_t *name); bool ThereIsMessage() const { return !Messages.IsEmpty() || FinalMessage.ThereIsMessage(); } }; @@ -151,11 +152,12 @@ class CProgressDialog: public NWindows::NControl::CModalDialog NWindows::NControl::CProgressBar m_ProgressBar; NWindows::NControl::CListView _messageList; - int _numMessages; + unsigned _numMessages; + UStringVector _messageStrings; - #ifdef __ITaskbarList3_INTERFACE_DEFINED__ + // #ifdef __ITaskbarList3_INTERFACE_DEFINED__ CMyComPtr<ITaskbarList3> _taskbarList; - #endif + // #endif HWND _hwndForTaskbar; UInt32 _prevTime; @@ -169,7 +171,9 @@ class CProgressDialog: public NWindows::NControl::CModalDialog UInt64 _processed_Prev; UInt64 _packed_Prev; UInt64 _ratio_Prev; + UString _filesStr_Prev; + UString _filesTotStr_Prev; unsigned _prevSpeed_MoveBits; UInt64 _prevSpeed; @@ -193,26 +197,29 @@ class CProgressDialog: public NWindows::NControl::CModalDialog bool _externalCloseMessageWasReceived; - #ifdef __ITaskbarList3_INTERFACE_DEFINED__ + // #ifdef __ITaskbarList3_INTERFACE_DEFINED__ void SetTaskbarProgressState(TBPFLAG tbpFlags) { if (_taskbarList && _hwndForTaskbar) _taskbarList->SetProgressState(_hwndForTaskbar, tbpFlags); } - #endif + // #endif void SetTaskbarProgressState(); void UpdateStatInfo(bool showAll); - bool OnTimer(WPARAM timerID, LPARAM callback); void SetProgressRange(UInt64 range); void SetProgressPos(UInt64 pos); - virtual bool OnInit(); - virtual bool OnSize(WPARAM wParam, int xSize, int ySize); - virtual void OnCancel(); - virtual void OnOK(); + virtual bool OnTimer(WPARAM timerID, LPARAM callback) Z7_override; + virtual bool OnInit() Z7_override; + virtual bool OnSize(WPARAM wParam, int xSize, int ySize) Z7_override; + virtual void OnCancel() Z7_override; + virtual void OnOK() Z7_override; + virtual bool OnNotify(UINT /* controlID */, LPNMHDR header) Z7_override; + void CopyToClipboard(); + NWindows::NSynchronization::CManualResetEvent _createDialogEvent; NWindows::NSynchronization::CManualResetEvent _dialogCreatedEvent; - #ifndef _SFX + #ifndef Z7_SFX void AddToTitle(LPCWSTR string); #endif @@ -220,11 +227,11 @@ class CProgressDialog: public NWindows::NControl::CModalDialog void SetPriorityText(); void OnPauseButton(); void OnPriorityButton(); - bool OnButtonClicked(int buttonID, HWND buttonHWND); - bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam); + bool OnButtonClicked(unsigned buttonID, HWND buttonHWND) Z7_override; + bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam) Z7_override; void SetTitleText(); - void ShowSize(int id, UInt64 val, UInt64 &prev); + void ShowSize(unsigned id, UInt64 val, UInt64 &prev); void UpdateMessagesDialog(); @@ -246,10 +253,10 @@ public: int IconID; HWND MainWindow; - #ifndef _SFX + #ifndef Z7_SFX UString MainTitle; UString MainAddTitle; - ~CProgressDialog(); + ~CProgressDialog() Z7_DESTRUCTOR_override; #endif CProgressDialog(); @@ -259,9 +266,20 @@ public: _dialogCreatedEvent.Lock(); } - INT_PTR Create(const UString &title, NWindows::CThread &thread, HWND wndParent = 0); + INT_PTR Create(const UString &title, NWindows::CThread &thread, HWND wndParent = NULL); + + + /* how it works: + 1) the working thread calls ProcessWasFinished() + that sends kCloseMessage message to CProgressDialog (GUI) thread + 2) CProgressDialog (GUI) thread receives kCloseMessage message and + calls ProcessWasFinished_GuiVirt(); + So we can implement ProcessWasFinished_GuiVirt() and show special + results window in GUI thread with CProgressDialog as parent window + */ void ProcessWasFinished(); + virtual void ProcessWasFinished_GuiVirt() {} }; @@ -273,7 +291,8 @@ public: ~CProgressCloser() { _p->ProcessWasFinished(); } }; -class CProgressThreadVirt + +class CProgressThreadVirt: public CProgressDialog { protected: FStringVector ErrorPaths; @@ -281,33 +300,59 @@ protected: // error if any of HRESULT, ErrorMessage, ErrorPath virtual HRESULT ProcessVirt() = 0; - void Process(); public: HRESULT Result; bool ThreadFinishedOK; // if there is no fatal exception - CProgressDialog ProgressDialog; - - static THREAD_FUNC_DECL MyThreadFunction(void *param) - { - CProgressThreadVirt *p = (CProgressThreadVirt *)param; - try - { - p->Process(); - p->ThreadFinishedOK = true; - } - catch (...) { p->Result = E_FAIL; } - return 0; - } + void Process(); void AddErrorPath(const FString &path) { ErrorPaths.Add(path); } - HRESULT Create(const UString &title, HWND parentWindow = 0); + HRESULT Create(const UString &title, HWND parentWindow = NULL); CProgressThreadVirt(): Result(E_FAIL), ThreadFinishedOK(false) {} CProgressMessageBoxPair &GetMessagePair(bool isError) { return isError ? FinalMessage.ErrorMessage : FinalMessage.OkMessage; } - }; UString HResultToMessage(HRESULT errorCode); +/* +how it works: + +client code inherits CProgressThreadVirt and calls +CProgressThreadVirt::Create() +{ + it creates new thread that calls CProgressThreadVirt::Process(); + it creates modal progress dialog window with ProgressDialog.Create() +} + +CProgressThreadVirt::Process() +{ + { + Result = ProcessVirt(); // virtual function that must implement real work + } + if (exceptions) or FinalMessage.ErrorMessage.Message + { + set message to ProgressDialog.Sync.FinalMessage.ErrorMessage.Message + } + else if (FinalMessage.OkMessage.Message) + { + set message to ProgressDialog.Sync.FinalMessage.OkMessage + } + + PostMsg(kCloseMessage); +} + + +CProgressDialog::OnExternalCloseMessage() +{ + if (ProgressDialog.Sync.FinalMessage) + { + WorkWasFinishedVirt(); + Show (ProgressDialog.Sync.FinalMessage) + MessagesDisplayed = true; + } +} + +*/ + #endif diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2Res.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2Res.h index b45d7b49506..736c7179a18 100644 --- a/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2Res.h +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2Res.h @@ -28,6 +28,7 @@ #define IDT_PROGRESS_PACKED_VAL 110 #define IDT_PROGRESS_FILES_VAL 111 +#define IDT_PROGRESS_FILES_TOTAL 112 #define IDT_PROGRESS_ELAPSED_VAL 120 #define IDT_PROGRESS_REMAINING_VAL 121 @@ -41,7 +42,7 @@ #ifdef UNDER_CE #define MY_PROGRESS_VAL_UNITS 44 #else -#define MY_PROGRESS_VAL_UNITS 76 +#define MY_PROGRESS_VAL_UNITS 72 #endif #define MY_PROGRESS_LABEL_UNITS_MIN 60 #define MY_PROGRESS_LABEL_UNITS_START 90 diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2a.rc b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2a.rc index e9713930be1..dc7d797ff72 100644 --- a/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2a.rc +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2a.rc @@ -44,30 +44,35 @@ DIALOG_ID DIALOG 0, 0, xs, ys MY_MODAL_RESIZE_DIALOG_STYLE MY_FONT CAPTION "Progress" { DEFPUSHBUTTON "&Background", IDB_PROGRESS_BACKGROUND, bx3, by, bxs, bys - PUSHBUTTON "&Pause", IDB_PAUSE bx2, by, bxs, bys + PUSHBUTTON "&Pause", IDB_PAUSE, bx2, by, bxs, bys PUSHBUTTON "Cancel", IDCANCEL, bx1, by, bxs, bys + LTEXT "Elapsed time:", IDT_PROGRESS_ELAPSED, m, y0, x0s, 8 LTEXT "Remaining time:", IDT_PROGRESS_REMAINING, m, y1, x0s, 8 LTEXT "Files:", IDT_PROGRESS_FILES, m, y2, x0s, 8 - LTEXT "Compression ratio:", IDT_PROGRESS_RATIO, m, y3, x0s, 8 + LTEXT "Errors:", IDT_PROGRESS_ERRORS, m, y4, x0s, 8 + LTEXT "Total size:", IDT_PROGRESS_TOTAL, x2, y0, x2s, 8 LTEXT "Speed:", IDT_PROGRESS_SPEED, x2, y1, x2s, 8 LTEXT "Processed:", IDT_PROGRESS_PROCESSED,x2, y2, x2s, 8 LTEXT "Compressed size:" , IDT_PROGRESS_PACKED, x2, y3, x2s, 8 + LTEXT "Compression ratio:", IDT_PROGRESS_RATIO, x2, y4, x2s, 8 + RTEXT "", IDT_PROGRESS_ELAPSED_VAL, x1, y0, x1s, MY_TEXT_NOPREFIX RTEXT "", IDT_PROGRESS_REMAINING_VAL, x1, y1, x1s, MY_TEXT_NOPREFIX RTEXT "", IDT_PROGRESS_FILES_VAL, x1, y2, x1s, MY_TEXT_NOPREFIX - RTEXT "", IDT_PROGRESS_RATIO_VAL, x1, y3, x1s, MY_TEXT_NOPREFIX + RTEXT "", IDT_PROGRESS_FILES_TOTAL, x1, y3, x1s, MY_TEXT_NOPREFIX RTEXT "", IDT_PROGRESS_ERRORS_VAL, x1, y4, x1s, MY_TEXT_NOPREFIX RTEXT "", IDT_PROGRESS_TOTAL_VAL, x3, y0, x3s, MY_TEXT_NOPREFIX RTEXT "", IDT_PROGRESS_SPEED_VAL, x3, y1, x3s, MY_TEXT_NOPREFIX RTEXT "", IDT_PROGRESS_PROCESSED_VAL, x3, y2, x3s, MY_TEXT_NOPREFIX RTEXT "", IDT_PROGRESS_PACKED_VAL, x3, y3, x3s, MY_TEXT_NOPREFIX + RTEXT "", IDT_PROGRESS_RATIO_VAL, x3, y4, x3s, MY_TEXT_NOPREFIX LTEXT "", IDT_PROGRESS_STATUS, m, z3, xc, MY_TEXT_NOPREFIX CONTROL "", IDT_PROGRESS_FILE_NAME, "Static", SS_NOPREFIX | SS_LEFTNOWORDWRAP, m, z2, xc, z2s diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/PropertyName.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/PropertyName.h index 4f0d6dc11d9..fa6e5c54050 100644 --- a/3rdparty/lzma/CPP/7zip/UI/FileManager/PropertyName.h +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/PropertyName.h @@ -1,7 +1,7 @@ // PropertyName.h -#ifndef __PROPERTY_NAME_H -#define __PROPERTY_NAME_H +#ifndef ZIP7_INC_PROPERTY_NAME_H +#define ZIP7_INC_PROPERTY_NAME_H #include "../../../Common/MyString.h" diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/PropertyNameRes.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/PropertyNameRes.h index 67f339028fe..913887e4a42 100644 --- a/3rdparty/lzma/CPP/7zip/UI/FileManager/PropertyNameRes.h +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/PropertyNameRes.h @@ -93,3 +93,12 @@ #define IDS_PROP_READ_ONLY 1093 #define IDS_PROP_OUT_NAME 1094 #define IDS_PROP_COPY_LINK 1095 +#define IDS_PROP_ARC_FILE_NAME 1096 +#define IDS_PROP_IS_HASH 1097 +#define IDS_PROP_CHANGE_TIME 1098 +#define IDS_PROP_USER_ID 1099 +#define IDS_PROP_GROUP_ID 1100 +#define IDS_PROP_DEVICE_MAJOR 1101 +#define IDS_PROP_DEVICE_MINOR 1102 +#define IDS_PROP_DEV_MAJOR 1103 +#define IDS_PROP_DEV_MINOR 1104 diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/StdAfx.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/StdAfx.h new file mode 100644 index 00000000000..789cc6e7403 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/StdAfx.h @@ -0,0 +1,83 @@ +// StdAfx.h + +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif + +#include "../../../../C/Compiler.h" + +Z7_DIAGNOSCTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER +#ifndef _WIN32_WINNT +// #define _WIN32_WINNT 0x0400 +#define _WIN32_WINNT 0x0500 +// #define _WIN32_WINNT 0x0600 +// #define _WIN32_WINNT 0x0A00 +#endif +#ifndef WINVER +#define WINVER _WIN32_WINNT +#endif +// #define _WIN32_IE 0x400 // for debug +Z7_DIAGNOSCTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER + +#include "../../../Common/Common.h" +#include "../../../Common/MyWindows.h" + +#endif + +/* +WINVER and _WIN32_WINNT + +MSVC6 / 2003sdk: +{ + <windows.h> doesn't set _WIN32_WINNT + if WINVER is not set <windows.h> sets WINVER to value: + 0x0400 : MSVC6 + 0x0501 : Windows Server 2003 PSDK / 2003 R2 PSDK +} + +SDK for Win7 (and later) +{ + <windows.h> sets _WIN32_WINNT if it's not set. + <windows.h> sets WINVER if it's not set. +<windows.h> includes <sdkddkver.h> that does: +#if !defined(_WIN32_WINNT) && !defined(_CHICAGO_) + #define _WIN32_WINNT 0x0601 // in win7 sdk + #define _WIN32_WINNT 0x0A00 // in win10 sdk +#endif +#ifndef WINVER + #ifdef _WIN32_WINNT + #define WINVER _WIN32_WINNT + else + #define WINVER 0x0601 // in win7 sdk + #define WINVER 0x0A00 // in win10 sdk + endif +#endif +} + +Some GUI structures defined by windows will be larger, +If (_WIN32_WINNT) value is larger. + +Also if we send sizeof(win_gui_struct) to some windows function, +and we compile that code with big (_WIN32_WINNT) value, +the window function in old Windows can fail, if that old Windows +doesn't understand new big version of (win_gui_struct) compiled +with big (_WIN32_WINNT) value. + +So it's better to define smallest (_WIN32_WINNT) value here. +In 7-Zip FM we use some functions that require (_WIN32_WINNT == 0x0500). +So it's simpler to define (_WIN32_WINNT == 0x0500) here. +If we define (_WIN32_WINNT == 0x0400) here, we need some manual +declarations for functions and macros that require (0x0500) functions. +Also libs must contain these (0x0500+) functions. + +Some code in 7-zip FM uses also CommCtrl.h structures +that depend from (_WIN32_IE) value. But default +(_WIN32_IE) value from <windows.h> probably is OK for us. +So we don't set _WIN32_IE here. +default _WIN32_IE value set by <windows.h>: + 0x501 2003sdk + 0xa00 win10 sdk +*/ diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/SysIconUtils.cpp b/3rdparty/lzma/CPP/7zip/UI/FileManager/SysIconUtils.cpp index c8ea8b95aef..1c7cab00faf 100644 --- a/3rdparty/lzma/CPP/7zip/UI/FileManager/SysIconUtils.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/SysIconUtils.cpp @@ -10,7 +10,11 @@ #include "SysIconUtils.h" +#if defined(__MINGW32__) || defined(__MINGW64__) +#include <shlobj.h> +#else #include <ShlObj.h> +#endif #ifndef _UNICODE extern bool g_IsNT; @@ -18,48 +22,55 @@ extern bool g_IsNT; int GetIconIndexForCSIDL(int csidl) { - LPITEMIDLIST pidl = 0; + LPITEMIDLIST pidl = NULL; SHGetSpecialFolderLocation(NULL, csidl, &pidl); if (pidl) { SHFILEINFO shellInfo; - SHGetFileInfo(LPCTSTR(pidl), FILE_ATTRIBUTE_NORMAL, - &shellInfo, sizeof(shellInfo), - SHGFI_PIDL | SHGFI_SYSICONINDEX); - IMalloc *pMalloc; + shellInfo.iIcon = 0; + const DWORD_PTR res = SHGetFileInfo((LPCTSTR)(const void *)(pidl), FILE_ATTRIBUTE_NORMAL, + &shellInfo, sizeof(shellInfo), + SHGFI_PIDL | SHGFI_SYSICONINDEX); + /* + IMalloc *pMalloc; SHGetMalloc(&pMalloc); if (pMalloc) { pMalloc->Free(pidl); pMalloc->Release(); } - return shellInfo.iIcon; + */ + // we use OLE2.dll function here + CoTaskMemFree(pidl); + if (res) + return shellInfo.iIcon; } return 0; } #ifndef _UNICODE -typedef int (WINAPI * SHGetFileInfoWP)(LPCWSTR pszPath, DWORD attrib, SHFILEINFOW *psfi, UINT cbFileInfo, UINT uFlags); +typedef DWORD_PTR (WINAPI * Func_SHGetFileInfoW)(LPCWSTR pszPath, DWORD attrib, SHFILEINFOW *psfi, UINT cbFileInfo, UINT uFlags); -struct CSHGetFileInfoInit +static struct C_SHGetFileInfo_Init { - SHGetFileInfoWP shGetFileInfoW; - CSHGetFileInfoInit() + Func_SHGetFileInfoW f_SHGetFileInfoW; + C_SHGetFileInfo_Init() { - shGetFileInfoW = (SHGetFileInfoWP) - ::GetProcAddress(::GetModuleHandleW(L"shell32.dll"), "SHGetFileInfoW"); + f_SHGetFileInfoW = Z7_GET_PROC_ADDRESS( + Func_SHGetFileInfoW, ::GetModuleHandleW(L"shell32.dll"), + "SHGetFileInfoW"); } -} g_SHGetFileInfoInit; +} g_SHGetFileInfo_Init; #endif -static DWORD_PTR MySHGetFileInfoW(LPCWSTR pszPath, DWORD attrib, SHFILEINFOW *psfi, UINT cbFileInfo, UINT uFlags) +static DWORD_PTR My_SHGetFileInfoW(LPCWSTR pszPath, DWORD attrib, SHFILEINFOW *psfi, UINT cbFileInfo, UINT uFlags) { #ifdef _UNICODE return SHGetFileInfo #else - if (g_SHGetFileInfoInit.shGetFileInfoW == 0) + if (!g_SHGetFileInfo_Init.f_SHGetFileInfoW) return 0; - return g_SHGetFileInfoInit.shGetFileInfoW + return g_SHGetFileInfo_Init.f_SHGetFileInfoW #endif (pszPath, attrib, psfi, cbFileInfo, uFlags); } @@ -70,7 +81,7 @@ DWORD_PTR GetRealIconIndex(CFSTR path, DWORD attrib, int &iconIndex) if (!g_IsNT) { SHFILEINFO shellInfo; - DWORD_PTR res = ::SHGetFileInfo(fs2fas(path), FILE_ATTRIBUTE_NORMAL | attrib, &shellInfo, + const DWORD_PTR res = ::SHGetFileInfo(fs2fas(path), FILE_ATTRIBUTE_NORMAL | attrib, &shellInfo, sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX); iconIndex = shellInfo.iIcon; return res; @@ -79,7 +90,7 @@ DWORD_PTR GetRealIconIndex(CFSTR path, DWORD attrib, int &iconIndex) #endif { SHFILEINFOW shellInfo; - DWORD_PTR res = ::MySHGetFileInfoW(fs2us(path), FILE_ATTRIBUTE_NORMAL | attrib, &shellInfo, + const DWORD_PTR res = ::My_SHGetFileInfoW(fs2us(path), FILE_ATTRIBUTE_NORMAL | attrib, &shellInfo, sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX); iconIndex = shellInfo.iIcon; return res; @@ -106,7 +117,7 @@ DWORD_PTR GetRealIconIndex(const UString &fileName, DWORD attrib, int &iconIndex { SHFILEINFOW shellInfo; shellInfo.szTypeName[0] = 0; - DWORD_PTR res = ::MySHGetFileInfoW(fileName, FILE_ATTRIBUTE_NORMAL | attrib, &shellInfo, + DWORD_PTR res = ::My_SHGetFileInfoW(fileName, FILE_ATTRIBUTE_NORMAL | attrib, &shellInfo, sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX | SHGFI_TYPENAME); if (typeName) *typeName = shellInfo.szTypeName; @@ -116,15 +127,15 @@ DWORD_PTR GetRealIconIndex(const UString &fileName, DWORD attrib, int &iconIndex } */ -static int FindInSorted_Attrib(const CRecordVector<CAttribIconPair> &vect, DWORD attrib, int &insertPos) +static int FindInSorted_Attrib(const CRecordVector<CAttribIconPair> &vect, DWORD attrib, unsigned &insertPos) { unsigned left = 0, right = vect.Size(); while (left != right) { - unsigned mid = (left + right) / 2; - DWORD midAttrib = vect[mid].Attrib; + const unsigned mid = (left + right) / 2; + const DWORD midAttrib = vect[mid].Attrib; if (attrib == midAttrib) - return mid; + return (int)mid; if (attrib < midAttrib) right = mid; else @@ -134,15 +145,15 @@ static int FindInSorted_Attrib(const CRecordVector<CAttribIconPair> &vect, DWORD return -1; } -static int FindInSorted_Ext(const CObjectVector<CExtIconPair> &vect, const wchar_t *ext, int &insertPos) +static int FindInSorted_Ext(const CObjectVector<CExtIconPair> &vect, const wchar_t *ext, unsigned &insertPos) { unsigned left = 0, right = vect.Size(); while (left != right) { - unsigned mid = (left + right) / 2; - int compare = MyStringCompareNoCase(ext, vect[mid].Ext); + const unsigned mid = (left + right) / 2; + const int compare = MyStringCompareNoCase(ext, vect[mid].Ext); if (compare == 0) - return mid; + return (int)mid; if (compare < 0) right = mid; else @@ -158,11 +169,11 @@ int CExtToIconMap::GetIconIndex(DWORD attrib, const wchar_t *fileName /*, UStrin unsigned i; for (i = 0;; i++) { - wchar_t c = fileName[i]; + const wchar_t c = fileName[i]; if (c == 0) break; if (c == '.') - dotPos = i; + dotPos = (int)i; } /* @@ -177,12 +188,12 @@ int CExtToIconMap::GetIconIndex(DWORD attrib, const wchar_t *fileName /*, UStrin if ((attrib & FILE_ATTRIBUTE_DIRECTORY) != 0 || dotPos < 0) { - int insertPos = 0; - int index = FindInSorted_Attrib(_attribMap, attrib, insertPos); + unsigned insertPos = 0; + const int index = FindInSorted_Attrib(_attribMap, attrib, insertPos); if (index >= 0) { // if (typeName) *typeName = _attribMap[index].TypeName; - return _attribMap[index].IconIndex; + return _attribMap[(unsigned)index].IconIndex; } CAttribIconPair pair; GetRealIconIndex( @@ -207,8 +218,8 @@ int CExtToIconMap::GetIconIndex(DWORD attrib, const wchar_t *fileName /*, UStrin } const wchar_t *ext = fileName + dotPos + 1; - int insertPos = 0; - int index = FindInSorted_Ext(_extMap, ext, insertPos); + unsigned insertPos = 0; + const int index = FindInSorted_Ext(_extMap, ext, insertPos); if (index >= 0) { const CExtIconPair &pa = _extMap[index]; @@ -218,7 +229,7 @@ int CExtToIconMap::GetIconIndex(DWORD attrib, const wchar_t *fileName /*, UStrin for (i = 0;; i++) { - wchar_t c = ext[i]; + const wchar_t c = ext[i]; if (c == 0) break; if (c < L'0' || c > L'9') @@ -253,3 +264,15 @@ int CExtToIconMap::GetIconIndex(DWORD attrib, const UString &fileName) return GetIconIndex(attrib, fileName, NULL); } */ + +HIMAGELIST GetSysImageList(bool smallIcons) +{ + SHFILEINFO shellInfo; + return (HIMAGELIST)SHGetFileInfo(TEXT(""), + FILE_ATTRIBUTE_NORMAL | + FILE_ATTRIBUTE_DIRECTORY, + &shellInfo, sizeof(shellInfo), + SHGFI_USEFILEATTRIBUTES | + SHGFI_SYSICONINDEX | + (smallIcons ? SHGFI_SMALLICON : SHGFI_ICON)); +} diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/SysIconUtils.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/SysIconUtils.h index f1b27fa1541..1d34ef6818f 100644 --- a/3rdparty/lzma/CPP/7zip/UI/FileManager/SysIconUtils.h +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/SysIconUtils.h @@ -1,11 +1,11 @@ // SysIconUtils.h -#ifndef __SYS_ICON_UTILS_H -#define __SYS_ICON_UTILS_H +#ifndef ZIP7_INC_SYS_ICON_UTILS_H +#define ZIP7_INC_SYS_ICON_UTILS_H #include "../../../Common/MyWindows.h" -#include <commctrl.h> +#include <CommCtrl.h> #include "../../../Common/MyString.h" @@ -50,13 +50,6 @@ public: DWORD_PTR GetRealIconIndex(CFSTR path, DWORD attrib, int &iconIndex); int GetIconIndexForCSIDL(int csidl); -inline HIMAGELIST GetSysImageList(bool smallIcons) -{ - SHFILEINFO shellInfo; - return (HIMAGELIST)SHGetFileInfo(TEXT(""), - FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_DIRECTORY, - &shellInfo, sizeof(shellInfo), - SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX | (smallIcons ? SHGFI_SMALLICON : SHGFI_ICON)); -} +HIMAGELIST GetSysImageList(bool smallIcons); #endif diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/resource.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/resource.h index b7ca17f1b22..9d605c6d43a 100644 --- a/3rdparty/lzma/CPP/7zip/UI/FileManager/resource.h +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/resource.h @@ -26,6 +26,14 @@ #define IDM_SHA1 104 #define IDM_SHA256 105 + +#define IDM_FILE 500 +#define IDM_EDIT 501 +#define IDM_VIEW 502 +#define IDM_FAVORITES 503 +#define IDM_TOOLS 504 +#define IDM_HELP 505 + #define IDM_OPEN 540 #define IDM_OPEN_INSIDE 541 #define IDM_OPEN_OUTSIDE 542 @@ -47,6 +55,11 @@ #define IDM_LINK 558 #define IDM_ALT_STREAMS 559 +#define IDM_VER_EDIT 580 +#define IDM_VER_COMMIT 581 +#define IDM_VER_REVERT 582 +#define IDM_VER_DIFF 583 + #define IDM_OPEN_INSIDE_ONE 590 #define IDM_OPEN_INSIDE_PARSER 591 @@ -85,6 +98,10 @@ #define IDM_VIEW_TOOLBARS_LARGE_BUTTONS 752 #define IDM_VIEW_TOOLBARS_SHOW_BUTTONS_TEXT 753 +#define IDM_VIEW_TIME_POPUP 760 +#define IDM_VIEW_TIME 761 + +#define IDM_ADD_TO_FAVORITES 800 #define IDS_BOOKMARK 801 #define IDM_OPTIONS 900 diff --git a/3rdparty/lzma/CPP/7zip/UI/GUI/7zG.exe.manifest b/3rdparty/lzma/CPP/7zip/UI/GUI/7zG.exe.manifest new file mode 100644 index 00000000000..ae964d82036 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/GUI/7zG.exe.manifest @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3"> + <assemblyIdentity version="1.0.0.0" processorArchitecture="*" name="7-Zip.7-Zip.7zG" type="win32"/> + <description>7-Zip GUI.</description> + <dependency> + <dependentAssembly><assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/></dependentAssembly> + </dependency> +<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"><application> +<!-- Vista --> <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> +<!-- Win 7 --> <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> +<!-- Win 8 --> <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> +<!-- Win 8.1 --> <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> +<!-- Win 10 --> <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> +</application></compatibility> + <asmv3:application> + <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings"> + <dpiAware>true</dpiAware> + </asmv3:windowsSettings> + </asmv3:application> +<application xmlns="urn:schemas-microsoft-com:asm.v3"> +<windowsSettings xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings"> +<ws2:longPathAware>true</ws2:longPathAware></windowsSettings></application> +</assembly> diff --git a/3rdparty/lzma/CPP/7zip/UI/GUI/Extract.rc b/3rdparty/lzma/CPP/7zip/UI/GUI/Extract.rc index f75b2e6fcb3..36bfb00945e 100644 --- a/3rdparty/lzma/CPP/7zip/UI/GUI/Extract.rc +++ b/3rdparty/lzma/CPP/7zip/UI/GUI/Extract.rc @@ -7,11 +7,11 @@ BEGIN IDS_MEM_ERROR "The system cannot allocate the required amount of memory" IDS_CANNOT_CREATE_FOLDER "Cannot create folder '{0}'" IDS_UPDATE_NOT_SUPPORTED "Update operations are not supported for this archive." - IDS_CANT_OPEN_ARCHIVE "Can not open file '{0}' as archive" - IDS_CANT_OPEN_ENCRYPTED_ARCHIVE "Can not open encrypted archive '{0}'. Wrong password?" + IDS_CANT_OPEN_ARCHIVE "Cannot open file '{0}' as archive" + IDS_CANT_OPEN_ENCRYPTED_ARCHIVE "Cannot open encrypted archive '{0}'. Wrong password?" IDS_UNSUPPORTED_ARCHIVE_TYPE "Unsupported archive type" - IDS_CANT_OPEN_AS_TYPE "Can not open the file as {0} archive" + IDS_CANT_OPEN_AS_TYPE "Cannot open the file as {0} archive" IDS_IS_OPEN_AS_TYPE "The file is open as {0} archive" IDS_IS_OPEN_WITH_OFFSET "The archive is open with offset" @@ -45,7 +45,7 @@ BEGIN IDS_EXTRACT_MSG_DATA_ERROR "Data error" IDS_EXTRACT_MSG_CRC_ERROR "CRC failed" IDS_EXTRACT_MSG_UNAVAILABLE_DATA "Unavailable data" - IDS_EXTRACT_MSG_UEXPECTED_END "Unexpected end of data"; + IDS_EXTRACT_MSG_UEXPECTED_END "Unexpected end of data" IDS_EXTRACT_MSG_DATA_AFTER_END "There are some data after the end of the payload data" IDS_EXTRACT_MSG_IS_NOT_ARC "Is not archive" IDS_EXTRACT_MSG_HEADERS_ERROR "Headers Error" diff --git a/3rdparty/lzma/CPP/7zip/UI/GUI/ExtractDialog.cpp b/3rdparty/lzma/CPP/7zip/UI/GUI/ExtractDialog.cpp index af47fc2d205..46284820392 100644 --- a/3rdparty/lzma/CPP/7zip/UI/GUI/ExtractDialog.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/GUI/ExtractDialog.cpp @@ -9,7 +9,7 @@ #include "../../../Windows/FileDir.h" #include "../../../Windows/ResourceString.h" -#ifndef NO_REGISTRY +#ifndef Z7_NO_REGISTRY #include "../FileManager/HelpUtils.h" #endif @@ -28,6 +28,8 @@ using namespace NName; extern HINSTANCE g_hInstance; +#ifndef Z7_SFX + static const UInt32 kPathMode_IDs[] = { IDS_EXTRACT_PATHS_FULL, @@ -44,8 +46,6 @@ static const UInt32 kOverwriteMode_IDs[] = IDS_EXTRACT_OVERWRITE_RENAME_EXISTING }; -#ifndef _SFX - static const // NExtract::NPathMode::EEnum int @@ -70,7 +70,7 @@ static const #endif -#ifdef LANG +#ifdef Z7_LANG static const UInt32 kLangIDs[] = { @@ -87,22 +87,23 @@ static const UInt32 kLangIDs[] = // static const int kWildcardsButtonIndex = 2; -#ifndef NO_REGISTRY +#ifndef Z7_NO_REGISTRY static const unsigned kHistorySize = 16; #endif -#ifndef _SFX +#ifndef Z7_SFX // it's used in CompressDialog also +void AddComboItems(NControl::CComboBox &combo, const UInt32 *langIDs, unsigned numItems, const int *values, int curVal); void AddComboItems(NControl::CComboBox &combo, const UInt32 *langIDs, unsigned numItems, const int *values, int curVal) { - int curSel = 0; + unsigned curSel = 0; for (unsigned i = 0; i < numItems; i++) { UString s = LangString(langIDs[i]); s.RemoveChar(L'&'); - int index = (int)combo.AddString(s); - combo.SetItemData(index, i); + const int index = (int)combo.AddString(s); + combo.SetItemData(index, (LPARAM)i); if (values[i] == curVal) curSel = i; } @@ -110,6 +111,7 @@ void AddComboItems(NControl::CComboBox &combo, const UInt32 *langIDs, unsigned n } // it's used in CompressDialog also +bool GetBoolsVal(const CBoolPair &b1, const CBoolPair &b2); bool GetBoolsVal(const CBoolPair &b1, const CBoolPair &b2) { if (b1.Def) return b1.Val; @@ -124,8 +126,8 @@ void CExtractDialog::CheckButton_TwoBools(UINT id, const CBoolPair &b1, const CB void CExtractDialog::GetButton_Bools(UINT id, CBoolPair &b1, CBoolPair &b2) { - bool val = IsButtonCheckedBool(id); - bool oldVal = GetBoolsVal(b1, b2); + const bool val = IsButtonCheckedBool(id); + const bool oldVal = GetBoolsVal(b1, b2); if (val != oldVal) b1.Def = b2.Def = true; b1.Val = b2.Val = val; @@ -135,7 +137,7 @@ void CExtractDialog::GetButton_Bools(UINT id, CBoolPair &b1, CBoolPair &b2) bool CExtractDialog::OnInit() { - #ifdef LANG + #ifdef Z7_LANG { UString s; LangString_OnlyFromLangFile(IDD_EXTRACT, s); @@ -143,23 +145,23 @@ bool CExtractDialog::OnInit() GetText(s); if (!ArcPath.IsEmpty()) { - s.AddAscii(" : "); + s += " : "; s += ArcPath; } SetText(s); // LangSetWindowText(*this, IDD_EXTRACT); - LangSetDlgItems(*this, kLangIDs, ARRAY_SIZE(kLangIDs)); + LangSetDlgItems(*this, kLangIDs, Z7_ARRAY_SIZE(kLangIDs)); } #endif - #ifndef _SFX + #ifndef Z7_SFX _passwordControl.Attach(GetItem(IDE_EXTRACT_PASSWORD)); _passwordControl.SetText(Password); _passwordControl.SetPasswordChar(TEXT('*')); _pathName.Attach(GetItem(IDE_EXTRACT_NAME)); #endif - #ifdef NO_REGISTRY + #ifdef Z7_NO_REGISTRY PathMode = NExtract::NPathMode::kFullPaths; OverwriteMode = NExtract::NOverwriteMode::kAsk; @@ -189,7 +191,7 @@ bool CExtractDialog::OnInit() UString pathPrefix = DirPath; - #ifndef _SFX + #ifndef Z7_SFX if (_info.SplitDest.Val) { @@ -208,7 +210,7 @@ bool CExtractDialog::OnInit() _path.SetText(pathPrefix); - #ifndef NO_REGISTRY + #ifndef Z7_NO_REGISTRY for (unsigned i = 0; i < _info.Paths.Size() && i < kHistorySize; i++) _path.AddString(_info.Paths[i]); #endif @@ -220,13 +222,13 @@ bool CExtractDialog::OnInit() _path.SetCurSel(-1); */ - #ifndef _SFX + #ifndef Z7_SFX _pathMode.Attach(GetItem(IDC_EXTRACT_PATH_MODE)); _overwriteMode.Attach(GetItem(IDC_EXTRACT_OVERWRITE_MODE)); - AddComboItems(_pathMode, kPathMode_IDs, ARRAY_SIZE(kPathMode_IDs), kPathModeButtonsVals, PathMode); - AddComboItems(_overwriteMode, kOverwriteMode_IDs, ARRAY_SIZE(kOverwriteMode_IDs), kOverwriteButtonsVals, OverwriteMode); + AddComboItems(_pathMode, kPathMode_IDs, Z7_ARRAY_SIZE(kPathMode_IDs), kPathModeButtonsVals, PathMode); + AddComboItems(_overwriteMode, kOverwriteMode_IDs, Z7_ARRAY_SIZE(kOverwriteMode_IDs), kOverwriteButtonsVals, OverwriteMode); #endif @@ -241,7 +243,7 @@ bool CExtractDialog::OnInit() return CModalDialog::OnInit(); } -#ifndef _SFX +#ifndef Z7_SFX void CExtractDialog::UpdatePasswordControl() { _passwordControl.SetPasswordChar(IsShowPasswordChecked() ? 0 : TEXT('*')); @@ -251,14 +253,14 @@ void CExtractDialog::UpdatePasswordControl() } #endif -bool CExtractDialog::OnButtonClicked(int buttonID, HWND buttonHWND) +bool CExtractDialog::OnButtonClicked(unsigned buttonID, HWND buttonHWND) { switch (buttonID) { case IDB_EXTRACT_SET_PATH: OnButtonSetPath(); return true; - #ifndef _SFX + #ifndef Z7_SFX case IDX_EXTRACT_NAME_ENABLE: ShowItem_Bool(IDE_EXTRACT_NAME, IsButtonCheckedBool(IDX_EXTRACT_NAME_ENABLE)); return true; @@ -280,12 +282,13 @@ void CExtractDialog::OnButtonSetPath() UString resultPath; if (!MyBrowseForFolder(*this, title, currentPath, resultPath)) return; - #ifndef NO_REGISTRY + #ifndef Z7_NO_REGISTRY _path.SetCurSel(-1); #endif _path.SetText(resultPath); } +void AddUniqueString(UStringVector &list, const UString &s); void AddUniqueString(UStringVector &list, const UString &s) { FOR_VECTOR (i, list) @@ -296,7 +299,7 @@ void AddUniqueString(UStringVector &list, const UString &s) void CExtractDialog::OnOK() { - #ifndef _SFX + #ifndef Z7_SFX int pathMode2 = kPathModeButtonsVals[_pathMode.GetCurSel()]; if (PathMode != NExtract::NPathMode::kCurPaths || pathMode2 != NExtract::NPathMode::kFullPaths) @@ -310,7 +313,7 @@ void CExtractDialog::OnOK() #endif - #ifndef NO_REGISTRY + #ifndef Z7_NO_REGISTRY // GetButton_Bools(IDX_EXTRACT_ALT_STREAMS, AltStreams, _info.AltStreams); GetButton_Bools(IDX_EXTRACT_NT_SECUR, NtSecurity, _info.NtSecurity); @@ -347,7 +350,7 @@ void CExtractDialog::OnOK() UString s; - #ifdef NO_REGISTRY + #ifdef Z7_NO_REGISTRY _path.GetText(s); @@ -357,7 +360,7 @@ void CExtractDialog::OnOK() if (currentItem == CB_ERR) { _path.GetText(s); - if (_path.GetCount() >= kHistorySize) + if (_path.GetCount() >= (int)kHistorySize) currentItem = _path.GetCount() - 1; } else @@ -368,9 +371,9 @@ void CExtractDialog::OnOK() s.Trim(); NName::NormalizeDirPathPrefix(s); - #ifndef _SFX + #ifndef Z7_SFX - bool splitDest = IsButtonCheckedBool(IDX_EXTRACT_NAME_ENABLE); + const bool splitDest = IsButtonCheckedBool(IDX_EXTRACT_NAME_ENABLE); if (splitDest) { UString pathName; @@ -389,9 +392,9 @@ void CExtractDialog::OnOK() DirPath = s; - #ifndef NO_REGISTRY + #ifndef Z7_NO_REGISTRY _info.Paths.Clear(); - #ifndef _SFX + #ifndef Z7_SFX AddUniqueString(_info.Paths, s); #endif for (int i = 0; i < _path.GetCount(); i++) @@ -408,11 +411,11 @@ void CExtractDialog::OnOK() CModalDialog::OnOK(); } -#ifndef NO_REGISTRY -static LPCWSTR kHelpTopic = L"fm/plugins/7-zip/extract.htm"; +#ifndef Z7_NO_REGISTRY +#define kHelpTopic "fm/plugins/7-zip/extract.htm" void CExtractDialog::OnHelp() { - ShowHelpWindow(NULL, kHelpTopic); + ShowHelpWindow(kHelpTopic); CModalDialog::OnHelp(); } #endif diff --git a/3rdparty/lzma/CPP/7zip/UI/GUI/ExtractDialog.h b/3rdparty/lzma/CPP/7zip/UI/GUI/ExtractDialog.h index 33349ffc615..1565fb8ab4d 100644 --- a/3rdparty/lzma/CPP/7zip/UI/GUI/ExtractDialog.h +++ b/3rdparty/lzma/CPP/7zip/UI/GUI/ExtractDialog.h @@ -1,7 +1,7 @@ // ExtractDialog.h -#ifndef __EXTRACT_DIALOG_H -#define __EXTRACT_DIALOG_H +#ifndef ZIP7_INC_EXTRACT_DIALOG_H +#define ZIP7_INC_EXTRACT_DIALOG_H #include "ExtractDialogRes.h" @@ -12,7 +12,7 @@ #include "../FileManager/DialogSize.h" -#ifndef NO_REGISTRY +#ifndef Z7_NO_REGISTRY #include "../Common/ZipRegistry.h" #endif @@ -33,20 +33,20 @@ namespace NExtractionDialog class CExtractDialog: public NWindows::NControl::CModalDialog { - #ifdef NO_REGISTRY + #ifdef Z7_NO_REGISTRY NWindows::NControl::CDialogChildControl _path; #else NWindows::NControl::CComboBox _path; #endif - #ifndef _SFX + #ifndef Z7_SFX NWindows::NControl::CEdit _pathName; NWindows::NControl::CEdit _passwordControl; NWindows::NControl::CComboBox _pathMode; NWindows::NControl::CComboBox _overwriteMode; #endif - #ifndef _SFX + #ifndef Z7_SFX // int GetFilesMode() const; void UpdatePasswordControl(); #endif @@ -55,13 +55,13 @@ class CExtractDialog: public NWindows::NControl::CModalDialog void CheckButton_TwoBools(UINT id, const CBoolPair &b1, const CBoolPair &b2); void GetButton_Bools(UINT id, CBoolPair &b1, CBoolPair &b2); - virtual bool OnInit(); - virtual bool OnButtonClicked(int buttonID, HWND buttonHWND); - virtual void OnOK(); + virtual bool OnInit() Z7_override; + virtual bool OnButtonClicked(unsigned buttonID, HWND buttonHWND) Z7_override; + virtual void OnOK() Z7_override; - #ifndef NO_REGISTRY + #ifndef Z7_NO_REGISTRY - virtual void OnHelp(); + virtual void OnHelp() Z7_override; NExtract::CInfo _info; @@ -76,7 +76,7 @@ public: UString DirPath; UString ArcPath; - #ifndef _SFX + #ifndef Z7_SFX UString Password; #endif bool PathMode_Force; @@ -84,16 +84,16 @@ public: NExtract::NPathMode::EEnum PathMode; NExtract::NOverwriteMode::EEnum OverwriteMode; - #ifndef _SFX + #ifndef Z7_SFX // CBoolPair AltStreams; CBoolPair NtSecurity; #endif CBoolPair ElimDup; - INT_PTR Create(HWND aWndParent = 0) + INT_PTR Create(HWND aWndParent = NULL) { - #ifdef _SFX + #ifdef Z7_SFX BIG_DIALOG_SIZE(240, 64); #else BIG_DIALOG_SIZE(300, 160); diff --git a/3rdparty/lzma/CPP/7zip/UI/GUI/ExtractGUI.cpp b/3rdparty/lzma/CPP/7zip/UI/GUI/ExtractGUI.cpp index 7fb843a15fc..fdf3cc78a50 100644 --- a/3rdparty/lzma/CPP/7zip/UI/GUI/ExtractGUI.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/GUI/ExtractGUI.cpp @@ -34,37 +34,25 @@ using namespace NWindows; using namespace NFile; using namespace NDir; -static const wchar_t *kIncorrectOutDir = L"Incorrect output directory path"; +static const wchar_t * const kIncorrectOutDir = L"Incorrect output directory path"; -#ifndef _SFX +#ifndef Z7_SFX static void AddValuePair(UString &s, UINT resourceID, UInt64 value, bool addColon = true) { AddLangString(s, resourceID); if (addColon) - s += L':'; + s += ':'; s.Add_Space(); - char sz[32]; - ConvertUInt64ToString(value, sz); - s.AddAscii(sz); + s.Add_UInt64(value); s.Add_LF(); } static void AddSizePair(UString &s, UINT resourceID, UInt64 value) { - wchar_t sz[32]; AddLangString(s, resourceID); - s += L": "; - ConvertUInt64ToString(value, sz); - s += MyFormatNew(IDS_FILE_SIZE, sz); - // s += sz; - if (value >= (1 << 20)) - { - ConvertUInt64ToString(value >> 20, sz); - s += L" ("; - s += sz; - s += L" MB)"; - } + s += ": "; + AddSizeValue(s, value); s.Add_LF(); } @@ -72,8 +60,14 @@ static void AddSizePair(UString &s, UINT resourceID, UInt64 value) class CThreadExtracting: public CProgressThreadVirt { - HRESULT ProcessVirt(); + HRESULT ProcessVirt() Z7_override; public: + /* + #ifdef Z7_EXTERNAL_CODECS + const CExternalCodecs *externalCodecs; + #endif + */ + CCodecs *codecs; CExtractCallbackImp *ExtractCallbackSpec; const CObjectVector<COpenType> *FormatIndices; @@ -83,39 +77,70 @@ public: UStringVector *ArchivePathsFull; const NWildcard::CCensorNode *WildcardCensor; const CExtractOptions *Options; - #ifndef _SFX + + #ifndef Z7_SFX CHashBundle *HashBundle; + virtual void ProcessWasFinished_GuiVirt() Z7_override; #endif - CMyComPtr<IExtractCallbackUI> ExtractCallback; + + CMyComPtr<IFolderArchiveExtractCallback> FolderArchiveExtractCallback; UString Title; + + CPropNameValPairs Pairs; }; + +#ifndef Z7_SFX +void CThreadExtracting::ProcessWasFinished_GuiVirt() +{ + if (HashBundle && !Pairs.IsEmpty()) + ShowHashResults(Pairs, *this); +} +#endif + HRESULT CThreadExtracting::ProcessVirt() { CDecompressStat Stat; - #ifndef _SFX + + #ifndef Z7_SFX + /* if (HashBundle) HashBundle->Init(); + */ #endif - HRESULT res = Extract(codecs, + HRESULT res = Extract( + /* + #ifdef Z7_EXTERNAL_CODECS + externalCodecs, + #endif + */ + codecs, *FormatIndices, *ExcludedFormatIndices, *ArchivePaths, *ArchivePathsFull, - *WildcardCensor, *Options, ExtractCallbackSpec, ExtractCallback, - #ifndef _SFX + *WildcardCensor, *Options, + ExtractCallbackSpec, ExtractCallbackSpec, FolderArchiveExtractCallback, + #ifndef Z7_SFX HashBundle, #endif FinalMessage.ErrorMessage.Message, Stat); - #ifndef _SFX - if (res == S_OK && Options->TestMode && ExtractCallbackSpec->IsOK()) + + #ifndef Z7_SFX + if (res == S_OK && ExtractCallbackSpec->IsOK()) { - UString s; + if (HashBundle) + { + AddValuePair(Pairs, IDS_ARCHIVES_COLON, Stat.NumArchives); + AddSizeValuePair(Pairs, IDS_PROP_PACKED_SIZE, Stat.PackSize); + AddHashBundleRes(Pairs, *HashBundle); + } + else if (Options->TestMode) + { + UString s; - AddValuePair(s, IDS_ARCHIVES_COLON, Stat.NumArchives, false); - AddSizePair(s, IDS_PROP_PACKED_SIZE, Stat.PackSize); + AddValuePair(s, IDS_ARCHIVES_COLON, Stat.NumArchives, false); + AddSizePair(s, IDS_PROP_PACKED_SIZE, Stat.PackSize); - if (!HashBundle) - { if (Stat.NumFolders != 0) AddValuePair(s, IDS_PROP_FOLDERS, Stat.NumFolders); AddValuePair(s, IDS_PROP_FILES, Stat.NumFiles); @@ -126,25 +151,21 @@ HRESULT CThreadExtracting::ProcessVirt() AddValuePair(s, IDS_PROP_NUM_ALT_STREAMS, Stat.NumAltStreams); AddSizePair(s, IDS_PROP_ALT_STREAMS_SIZE, Stat.AltStreams_UnpackSize); } - } - - if (HashBundle) - { s.Add_LF(); - AddHashBundleRes(s, *HashBundle, UString()); + AddLangString(s, IDS_MESSAGE_NO_ERRORS); + FinalMessage.OkMessage.Title = Title; + FinalMessage.OkMessage.Message = s; } - - s.Add_LF(); - AddLangString(s, IDS_MESSAGE_NO_ERRORS); - - FinalMessage.OkMessage.Title = Title; - FinalMessage.OkMessage.Message = s; } #endif + return res; } + + HRESULT ExtractGUI( + // DECL_EXTERNAL_CODECS_LOC_VARS CCodecs *codecs, const CObjectVector<COpenType> &formatIndices, const CIntVector &excludedFormatIndices, @@ -152,7 +173,7 @@ HRESULT ExtractGUI( UStringVector &archivePathsFull, const NWildcard::CCensorNode &wildcardCensor, CExtractOptions &options, - #ifndef _SFX + #ifndef Z7_SFX CHashBundle *hb, #endif bool showDialog, @@ -163,6 +184,11 @@ HRESULT ExtractGUI( messageWasDisplayed = false; CThreadExtracting extracter; + /* + #ifdef Z7_EXTERNAL_CODECS + extracter.externalCodecs = _externalCodecs; + #endif + */ extracter.codecs = codecs; extracter.FormatIndices = &formatIndices; extracter.ExcludedFormatIndices = &excludedFormatIndices; @@ -197,7 +223,7 @@ HRESULT ExtractGUI( if (archivePathsFull.Size() == 1) dialog.ArcPath = archivePathsFull[0]; - #ifndef _SFX + #ifndef Z7_SFX // dialog.AltStreams = options.NtOptions.AltStreams; dialog.NtSecurity = options.NtOptions.NtSecurity; if (extractCallback->PasswordIsDefined) @@ -213,7 +239,7 @@ HRESULT ExtractGUI( options.PathMode = dialog.PathMode; options.ElimDup = dialog.ElimDup; - #ifndef _SFX + #ifndef Z7_SFX // options.NtOptions.AltStreams = dialog.AltStreams; options.NtOptions.NtSecurity = dialog.NtSecurity; extractCallback->Password = dialog.Password; @@ -233,7 +259,7 @@ HRESULT ExtractGUI( { UString s = GetUnicodeString(NError::MyFormatMessage(GetLastError())); UString s2 = MyFormatNew(IDS_CANNOT_CREATE_FOLDER, - #ifdef LANG + #ifdef Z7_LANG 0x02000603, #endif options.OutputDir); @@ -249,24 +275,23 @@ HRESULT ExtractGUI( extracter.Title = title; extracter.ExtractCallbackSpec = extractCallback; - extracter.ExtractCallbackSpec->ProgressDialog = &extracter.ProgressDialog; - extracter.ExtractCallback = extractCallback; + extracter.ExtractCallbackSpec->ProgressDialog = &extracter; + extracter.FolderArchiveExtractCallback = extractCallback; extracter.ExtractCallbackSpec->Init(); - extracter.ProgressDialog.CompressingMode = false; + extracter.CompressingMode = false; extracter.ArchivePaths = &archivePaths; extracter.ArchivePathsFull = &archivePathsFull; extracter.WildcardCensor = &wildcardCensor; extracter.Options = &options; - #ifndef _SFX + #ifndef Z7_SFX extracter.HashBundle = hb; #endif - extracter.ProgressDialog.IconID = IDI_ICON; + extracter.IconID = IDI_ICON; - RINOK(extracter.Create(title, hwndParent)); - messageWasDisplayed = extracter.ThreadFinishedOK & - extracter.ProgressDialog.MessagesDisplayed; + RINOK(extracter.Create(title, hwndParent)) + messageWasDisplayed = extracter.ThreadFinishedOK && extracter.MessagesDisplayed; return extracter.Result; } diff --git a/3rdparty/lzma/CPP/7zip/UI/GUI/ExtractGUI.h b/3rdparty/lzma/CPP/7zip/UI/GUI/ExtractGUI.h index d55b30de15c..13ca6abf89f 100644 --- a/3rdparty/lzma/CPP/7zip/UI/GUI/ExtractGUI.h +++ b/3rdparty/lzma/CPP/7zip/UI/GUI/ExtractGUI.h @@ -1,7 +1,7 @@ // GUI/ExtractGUI.h -#ifndef __EXTRACT_GUI_H -#define __EXTRACT_GUI_H +#ifndef ZIP7_INC_EXTRACT_GUI_H +#define ZIP7_INC_EXTRACT_GUI_H #include "../Common/Extract.h" @@ -20,6 +20,7 @@ */ HRESULT ExtractGUI( + // DECL_EXTERNAL_CODECS_LOC_VARS CCodecs *codecs, const CObjectVector<COpenType> &formatIndices, const CIntVector &excludedFormatIndices, @@ -27,7 +28,7 @@ HRESULT ExtractGUI( UStringVector &archivePathsFull, const NWildcard::CCensorNode &wildcardCensor, CExtractOptions &options, - #ifndef _SFX + #ifndef Z7_SFX CHashBundle *hb, #endif bool showDialog, diff --git a/3rdparty/lzma/CPP/7zip/UI/GUI/HashGUI.h b/3rdparty/lzma/CPP/7zip/UI/GUI/HashGUI.h index 40340365abe..1ec9c47564e 100644 --- a/3rdparty/lzma/CPP/7zip/UI/GUI/HashGUI.h +++ b/3rdparty/lzma/CPP/7zip/UI/GUI/HashGUI.h @@ -1,9 +1,10 @@ // HashGUI.h -#ifndef __HASH_GUI_H -#define __HASH_GUI_H +#ifndef ZIP7_INC_HASH_GUI_H +#define ZIP7_INC_HASH_GUI_H #include "../Common/HashCalc.h" +#include "../Common/Property.h" HRESULT HashCalcGUI( DECL_EXTERNAL_CODECS_LOC_VARS @@ -11,6 +12,16 @@ HRESULT HashCalcGUI( const CHashOptions &options, bool &messageWasDisplayed); -void AddHashBundleRes(UString &s, const CHashBundle &hb, const UString &firstFileName); +typedef CObjectVector<CProperty> CPropNameValPairs; + +void AddValuePair(CPropNameValPairs &pairs, UINT resourceID, UInt64 value); +void AddSizeValue(UString &s, UInt64 value); +void AddSizeValuePair(CPropNameValPairs &pairs, UINT resourceID, UInt64 value); + +void AddHashBundleRes(CPropNameValPairs &s, const CHashBundle &hb); +void AddHashBundleRes(UString &s, const CHashBundle &hb); + +void ShowHashResults(const CPropNameValPairs &propPairs, HWND hwnd); +void ShowHashResults(const CHashBundle &hb, HWND hwnd); #endif diff --git a/3rdparty/lzma/CPP/7zip/cmpl_clang.mak b/3rdparty/lzma/CPP/7zip/cmpl_clang.mak new file mode 100644 index 00000000000..e62e1e62faa --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/cmpl_clang.mak @@ -0,0 +1,3 @@ +include ../../var_clang.mak +include ../../warn_clang.mak +include makefile.gcc diff --git a/3rdparty/lzma/CPP/7zip/cmpl_clang_arm64.mak b/3rdparty/lzma/CPP/7zip/cmpl_clang_arm64.mak new file mode 100644 index 00000000000..3f6b02bfcf5 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/cmpl_clang_arm64.mak @@ -0,0 +1,3 @@ +include ../../var_clang_arm64.mak +include ../../warn_clang.mak +include makefile.gcc diff --git a/3rdparty/lzma/CPP/7zip/cmpl_clang_x64.mak b/3rdparty/lzma/CPP/7zip/cmpl_clang_x64.mak new file mode 100644 index 00000000000..b61e2af6608 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/cmpl_clang_x64.mak @@ -0,0 +1,3 @@ +include ../../var_clang_x64.mak +include ../../warn_clang.mak +include makefile.gcc diff --git a/3rdparty/lzma/CPP/7zip/cmpl_clang_x86.mak b/3rdparty/lzma/CPP/7zip/cmpl_clang_x86.mak new file mode 100644 index 00000000000..0e5cb76c0b6 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/cmpl_clang_x86.mak @@ -0,0 +1,3 @@ +include ../../var_clang_x86.mak +include ../../warn_clang.mak +include makefile.gcc diff --git a/3rdparty/lzma/CPP/7zip/cmpl_gcc.mak b/3rdparty/lzma/CPP/7zip/cmpl_gcc.mak new file mode 100644 index 00000000000..7a1aef2e3f6 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/cmpl_gcc.mak @@ -0,0 +1,3 @@ +include ../../var_gcc.mak +include ../../warn_gcc.mak +include makefile.gcc diff --git a/3rdparty/lzma/CPP/7zip/cmpl_gcc_arm64.mak b/3rdparty/lzma/CPP/7zip/cmpl_gcc_arm64.mak new file mode 100644 index 00000000000..53a85844728 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/cmpl_gcc_arm64.mak @@ -0,0 +1,3 @@ +include ../../var_gcc_arm64.mak +include ../../warn_gcc.mak +include makefile.gcc diff --git a/3rdparty/lzma/CPP/7zip/cmpl_gcc_x64.mak b/3rdparty/lzma/CPP/7zip/cmpl_gcc_x64.mak new file mode 100644 index 00000000000..500c30e47b9 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/cmpl_gcc_x64.mak @@ -0,0 +1,3 @@ +include ../../var_gcc_x64.mak +include ../../warn_gcc.mak +include makefile.gcc diff --git a/3rdparty/lzma/CPP/7zip/cmpl_gcc_x86.mak b/3rdparty/lzma/CPP/7zip/cmpl_gcc_x86.mak new file mode 100644 index 00000000000..e7687070791 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/cmpl_gcc_x86.mak @@ -0,0 +1,3 @@ +include ../../var_gcc_x86.mak +include ../../warn_gcc.mak +include makefile.gcc diff --git a/3rdparty/lzma/CPP/7zip/cmpl_mac_arm64.mak b/3rdparty/lzma/CPP/7zip/cmpl_mac_arm64.mak new file mode 100644 index 00000000000..941028e9584 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/cmpl_mac_arm64.mak @@ -0,0 +1,3 @@ +include ../../var_mac_arm64.mak +include ../../warn_clang_mac.mak +include makefile.gcc diff --git a/3rdparty/lzma/CPP/7zip/cmpl_mac_x64.mak b/3rdparty/lzma/CPP/7zip/cmpl_mac_x64.mak new file mode 100644 index 00000000000..d3aa03967d9 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/cmpl_mac_x64.mak @@ -0,0 +1,3 @@ +include ../../var_mac_x64.mak +include ../../warn_clang_mac.mak +include makefile.gcc diff --git a/3rdparty/lzma/CPP/7zip/var_clang.mak b/3rdparty/lzma/CPP/7zip/var_clang.mak new file mode 100644 index 00000000000..a6df26e77c8 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/var_clang.mak @@ -0,0 +1,11 @@ +PLATFORM= +O=b/c +IS_X64= +IS_X86= +IS_ARM64= +CROSS_COMPILE= +MY_ARCH= +USE_ASM= +CC=$(CROSS_COMPILE)clang +CXX=$(CROSS_COMPILE)clang++ +USE_CLANG=1 diff --git a/3rdparty/lzma/CPP/7zip/var_clang_arm64.mak b/3rdparty/lzma/CPP/7zip/var_clang_arm64.mak new file mode 100644 index 00000000000..4b354096956 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/var_clang_arm64.mak @@ -0,0 +1,11 @@ +PLATFORM=arm64 +O=b/c_$(PLATFORM) +IS_X64= +IS_X86= +IS_ARM64=1 +CROSS_COMPILE= +MY_ARCH= +USE_ASM=1 +CC=$(CROSS_COMPILE)clang +CXX=$(CROSS_COMPILE)clang++ +USE_CLANG=1 diff --git a/3rdparty/lzma/CPP/7zip/var_clang_x64.mak b/3rdparty/lzma/CPP/7zip/var_clang_x64.mak new file mode 100644 index 00000000000..fefed51c5bd --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/var_clang_x64.mak @@ -0,0 +1,12 @@ +PLATFORM=x64 +O=b/c_$(PLATFORM) +IS_X64=1 +IS_X86= +IS_ARM64= +CROSS_COMPILE= +MY_ARCH= +USE_ASM=1 +CC=$(CROSS_COMPILE)clang +CXX=$(CROSS_COMPILE)clang++ +USE_CLANG=1 + diff --git a/3rdparty/lzma/CPP/7zip/var_clang_x86.mak b/3rdparty/lzma/CPP/7zip/var_clang_x86.mak new file mode 100644 index 00000000000..5f3c2d9cb15 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/var_clang_x86.mak @@ -0,0 +1,12 @@ +PLATFORM=x86 +O=b/c_$(PLATFORM) +IS_X64= +IS_X86=1 +IS_ARM64= +CROSS_COMPILE= +MY_ARCH=-m32 +USE_ASM=1 +CC=$(CROSS_COMPILE)clang +CXX=$(CROSS_COMPILE)clang++ +USE_CLANG=1 + diff --git a/3rdparty/lzma/CPP/7zip/var_gcc.mak b/3rdparty/lzma/CPP/7zip/var_gcc.mak new file mode 100644 index 00000000000..664491cf2fc --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/var_gcc.mak @@ -0,0 +1,12 @@ +PLATFORM= +O=b/g +IS_X64= +IS_X86= +IS_ARM64= +CROSS_COMPILE= +MY_ARCH= +USE_ASM= +CC=$(CROSS_COMPILE)gcc +CXX=$(CROSS_COMPILE)g++ + +# -march=armv8-a+crc+crypto diff --git a/3rdparty/lzma/CPP/7zip/var_gcc_arm64.mak b/3rdparty/lzma/CPP/7zip/var_gcc_arm64.mak new file mode 100644 index 00000000000..4bbb687dbb3 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/var_gcc_arm64.mak @@ -0,0 +1,12 @@ +PLATFORM=arm64 +O=b/g_$(PLATFORM) +IS_X64= +IS_X86= +IS_ARM64=1 +CROSS_COMPILE= +MY_ARCH=-mtune=cortex-a53 +USE_ASM=1 +CC=$(CROSS_COMPILE)gcc +CXX=$(CROSS_COMPILE)g++ + +# -march=armv8-a+crc+crypto diff --git a/3rdparty/lzma/CPP/7zip/var_gcc_x64.mak b/3rdparty/lzma/CPP/7zip/var_gcc_x64.mak new file mode 100644 index 00000000000..1acf604f5f2 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/var_gcc_x64.mak @@ -0,0 +1,10 @@ +PLATFORM=x64 +O=b/g_$(PLATFORM) +IS_X64=1 +IS_X86= +IS_ARM64= +CROSS_COMPILE= +MY_ARCH= +USE_ASM=1 +CC=$(CROSS_COMPILE)gcc +CXX=$(CROSS_COMPILE)g++ diff --git a/3rdparty/lzma/CPP/7zip/var_gcc_x86.mak b/3rdparty/lzma/CPP/7zip/var_gcc_x86.mak new file mode 100644 index 00000000000..288bf94bead --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/var_gcc_x86.mak @@ -0,0 +1,11 @@ +PLATFORM=x86 +O=b/g_$(PLATFORM) +IS_X64= +IS_X86=1 +IS_ARM64= +CROSS_COMPILE= +MY_ARCH=-m32 +USE_ASM=1 +CC=$(CROSS_COMPILE)gcc +CXX=$(CROSS_COMPILE)g++ + diff --git a/3rdparty/lzma/CPP/7zip/var_mac_arm64.mak b/3rdparty/lzma/CPP/7zip/var_mac_arm64.mak new file mode 100644 index 00000000000..adf5fa1d703 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/var_mac_arm64.mak @@ -0,0 +1,11 @@ +PLATFORM=arm64 +O=b/m_$(PLATFORM) +IS_X64= +IS_X86= +IS_ARM64=1 +CROSS_COMPILE= +MY_ARCH=-arch arm64 +USE_ASM=1 +CC=$(CROSS_COMPILE)clang +CXX=$(CROSS_COMPILE)clang++ +USE_CLANG=1 diff --git a/3rdparty/lzma/CPP/7zip/var_mac_x64.mak b/3rdparty/lzma/CPP/7zip/var_mac_x64.mak new file mode 100644 index 00000000000..13d7aa7fedf --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/var_mac_x64.mak @@ -0,0 +1,11 @@ +PLATFORM=x64 +O=b/m_$(PLATFORM) +IS_X64=1 +IS_X86= +IS_ARM64= +CROSS_COMPILE= +MY_ARCH=-arch x86_64 +USE_ASM= +CC=$(CROSS_COMPILE)clang +CXX=$(CROSS_COMPILE)clang++ +USE_CLANG=1 diff --git a/3rdparty/lzma/CPP/7zip/warn_clang.mak b/3rdparty/lzma/CPP/7zip/warn_clang.mak new file mode 100644 index 00000000000..0d007307071 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/warn_clang.mak @@ -0,0 +1,3 @@ +CFLAGS_WARN = -Weverything -Wfatal-errors +# CXX_STD_FLAGS = -std=c++11 +# CXX_STD_FLAGS = diff --git a/3rdparty/lzma/CPP/7zip/warn_clang_mac.mak b/3rdparty/lzma/CPP/7zip/warn_clang_mac.mak new file mode 100644 index 00000000000..ed936c588a2 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/warn_clang_mac.mak @@ -0,0 +1,9 @@ +CFLAGS_WARN = -Weverything -Wfatal-errors -Wno-poison-system-directories +CXX_STD_FLAGS = -std=c++98 +CXX_STD_FLAGS = -std=c++11 +CXX_STD_FLAGS = -std=c++14 +CXX_STD_FLAGS = -std=c++17 +CXX_STD_FLAGS = -std=c++20 +CXX_STD_FLAGS = -std=c++23 + +CXX_STD_FLAGS = -std=c++11 diff --git a/3rdparty/lzma/CPP/7zip/warn_gcc.mak b/3rdparty/lzma/CPP/7zip/warn_gcc.mak new file mode 100644 index 00000000000..7eb1f570bde --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/warn_gcc.mak @@ -0,0 +1,45 @@ +CFLAGS_WARN_GCC_4_8 = \ + -Waddress \ + -Waggressive-loop-optimizations \ + -Wattributes \ + -Wcast-align \ + -Wcomment \ + -Wdiv-by-zero \ + -Wformat-contains-nul \ + -Winit-self \ + -Wint-to-pointer-cast \ + -Wunused \ + -Wunused-macros \ + +CFLAGS_WARN_GCC_6 = $(CFLAGS_WARN_GCC_4_8)\ + -Wbool-compare \ + -Wduplicated-cond \ + +# -Wno-strict-aliasing + +CFLAGS_WARN_GCC_9 = $(CFLAGS_WARN_GCC_6)\ + -Waddress-of-packed-member \ + -Wbool-operation \ + -Wcast-align=strict \ + -Wconversion \ + -Wdangling-else \ + -Wduplicated-branches \ + -Wimplicit-fallthrough=5 \ + -Wint-in-bool-context \ + -Wmaybe-uninitialized \ + -Wmisleading-indentation \ + -Wmissing-attributes + +# In C: -Wsign-conversion enabled also by -Wconversion +# -Wno-sign-conversion \ + + +CFLAGS_WARN_GCC_PPMD_UNALIGNED = \ + -Wno-strict-aliasing \ + + +# CFLAGS_WARN = $(CFLAGS_WARN_GCC_4_8) +CFLAGS_WARN = $(CFLAGS_WARN_GCC_9) + +# CXX_STD_FLAGS = -std=c++11 +# CXX_STD_FLAGS = |