Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x[-rw-r--r--]Asm/arm/7zCrcOpt.asm0
-rwxr-xr-x[-rw-r--r--]Asm/arm64/7zAsm.S0
-rwxr-xr-x[-rw-r--r--]Asm/arm64/LzmaDecOpt.S0
-rwxr-xr-x[-rw-r--r--]Asm/x86/7zAsm.asm7
-rwxr-xr-x[-rw-r--r--]Asm/x86/7zCrcOpt.asm0
-rwxr-xr-x[-rw-r--r--]Asm/x86/AesOpt.asm0
-rwxr-xr-x[-rw-r--r--]Asm/x86/LzFindOpt.asm0
-rwxr-xr-x[-rw-r--r--]Asm/x86/LzmaDecOpt.asm0
-rwxr-xr-x[-rw-r--r--]Asm/x86/Sha1Opt.asm0
-rwxr-xr-x[-rw-r--r--]Asm/x86/Sha256Opt.asm32
-rwxr-xr-x[-rw-r--r--]Asm/x86/XzCrc64Opt.asm0
-rwxr-xr-x[-rw-r--r--]C/7z.h0
-rwxr-xr-x[-rw-r--r--]C/7zAlloc.c0
-rwxr-xr-x[-rw-r--r--]C/7zAlloc.h0
-rwxr-xr-x[-rw-r--r--]C/7zArcIn.c0
-rwxr-xr-x[-rw-r--r--]C/7zBuf.c0
-rwxr-xr-x[-rw-r--r--]C/7zBuf.h0
-rwxr-xr-x[-rw-r--r--]C/7zBuf2.c0
-rwxr-xr-x[-rw-r--r--]C/7zCrc.c0
-rwxr-xr-x[-rw-r--r--]C/7zCrc.h0
-rwxr-xr-x[-rw-r--r--]C/7zCrcOpt.c0
-rwxr-xr-x[-rw-r--r--]C/7zDec.c0
-rwxr-xr-x[-rw-r--r--]C/7zFile.c0
-rwxr-xr-x[-rw-r--r--]C/7zFile.h0
-rwxr-xr-x[-rw-r--r--]C/7zStream.c0
-rwxr-xr-x[-rw-r--r--]C/7zTypes.h14
-rwxr-xr-x[-rw-r--r--]C/7zVersion.h10
-rwxr-xr-x[-rw-r--r--]C/7zVersion.rc0
-rwxr-xr-x[-rw-r--r--]C/7zip_gcc_c.mak0
-rwxr-xr-x[-rw-r--r--]C/Aes.c0
-rwxr-xr-x[-rw-r--r--]C/Aes.h0
-rwxr-xr-x[-rw-r--r--]C/AesOpt.c0
-rwxr-xr-x[-rw-r--r--]C/Alloc.c0
-rwxr-xr-x[-rw-r--r--]C/Alloc.h0
-rwxr-xr-x[-rw-r--r--]C/Bcj2.c0
-rwxr-xr-x[-rw-r--r--]C/Bcj2.h0
-rwxr-xr-x[-rw-r--r--]C/Bcj2Enc.c0
-rwxr-xr-x[-rw-r--r--]C/Blake2.h0
-rwxr-xr-x[-rw-r--r--]C/Blake2s.c0
-rwxr-xr-x[-rw-r--r--]C/Bra.c0
-rwxr-xr-x[-rw-r--r--]C/Bra.h0
-rwxr-xr-x[-rw-r--r--]C/Bra86.c0
-rwxr-xr-x[-rw-r--r--]C/BraIA64.c0
-rwxr-xr-x[-rw-r--r--]C/BwtSort.c0
-rwxr-xr-x[-rw-r--r--]C/BwtSort.h0
-rwxr-xr-x[-rw-r--r--]C/Compiler.h0
-rwxr-xr-x[-rw-r--r--]C/CpuArch.c0
-rwxr-xr-x[-rw-r--r--]C/CpuArch.h0
-rwxr-xr-x[-rw-r--r--]C/Delta.c0
-rwxr-xr-x[-rw-r--r--]C/Delta.h0
-rwxr-xr-x[-rw-r--r--]C/DllSecur.c0
-rwxr-xr-x[-rw-r--r--]C/DllSecur.h0
-rwxr-xr-x[-rw-r--r--]C/HuffEnc.c0
-rwxr-xr-x[-rw-r--r--]C/HuffEnc.h0
-rwxr-xr-x[-rw-r--r--]C/LzFind.c0
-rwxr-xr-x[-rw-r--r--]C/LzFind.h0
-rwxr-xr-x[-rw-r--r--]C/LzFindMt.c0
-rwxr-xr-x[-rw-r--r--]C/LzFindMt.h0
-rwxr-xr-x[-rw-r--r--]C/LzFindOpt.c0
-rwxr-xr-x[-rw-r--r--]C/LzHash.h0
-rwxr-xr-x[-rw-r--r--]C/Lzma2Dec.c0
-rwxr-xr-x[-rw-r--r--]C/Lzma2Dec.h0
-rwxr-xr-x[-rw-r--r--]C/Lzma2DecMt.c0
-rwxr-xr-x[-rw-r--r--]C/Lzma2DecMt.h0
-rwxr-xr-x[-rw-r--r--]C/Lzma2Enc.c0
-rwxr-xr-x[-rw-r--r--]C/Lzma2Enc.h0
-rwxr-xr-x[-rw-r--r--]C/Lzma86.h0
-rwxr-xr-x[-rw-r--r--]C/Lzma86Dec.c0
-rwxr-xr-x[-rw-r--r--]C/Lzma86Enc.c0
-rwxr-xr-x[-rw-r--r--]C/LzmaDec.c0
-rwxr-xr-x[-rw-r--r--]C/LzmaDec.h0
-rwxr-xr-x[-rw-r--r--]C/LzmaEnc.c0
-rwxr-xr-x[-rw-r--r--]C/LzmaEnc.h0
-rwxr-xr-x[-rw-r--r--]C/LzmaLib.c0
-rwxr-xr-x[-rw-r--r--]C/LzmaLib.h0
-rwxr-xr-x[-rw-r--r--]C/MtCoder.c0
-rwxr-xr-x[-rw-r--r--]C/MtCoder.h0
-rwxr-xr-x[-rw-r--r--]C/MtDec.c0
-rwxr-xr-x[-rw-r--r--]C/MtDec.h0
-rwxr-xr-x[-rw-r--r--]C/Ppmd.h0
-rwxr-xr-x[-rw-r--r--]C/Ppmd7.c0
-rwxr-xr-x[-rw-r--r--]C/Ppmd7.h0
-rwxr-xr-x[-rw-r--r--]C/Ppmd7Dec.c0
-rwxr-xr-x[-rw-r--r--]C/Ppmd7Enc.c0
-rwxr-xr-x[-rw-r--r--]C/Ppmd7aDec.c0
-rwxr-xr-x[-rw-r--r--]C/Ppmd8.c0
-rwxr-xr-x[-rw-r--r--]C/Ppmd8.h0
-rwxr-xr-x[-rw-r--r--]C/Ppmd8Dec.c0
-rwxr-xr-x[-rw-r--r--]C/Ppmd8Enc.c0
-rwxr-xr-x[-rw-r--r--]C/Precomp.h0
-rwxr-xr-x[-rw-r--r--]C/RotateDefs.h0
-rwxr-xr-x[-rw-r--r--]C/Sha1.c0
-rwxr-xr-x[-rw-r--r--]C/Sha1.h0
-rwxr-xr-x[-rw-r--r--]C/Sha1Opt.c0
-rwxr-xr-x[-rw-r--r--]C/Sha256.c0
-rwxr-xr-x[-rw-r--r--]C/Sha256.h0
-rwxr-xr-x[-rw-r--r--]C/Sha256Opt.c0
-rwxr-xr-x[-rw-r--r--]C/Sort.c0
-rwxr-xr-x[-rw-r--r--]C/Sort.h0
-rwxr-xr-x[-rw-r--r--]C/Threads.c0
-rwxr-xr-x[-rw-r--r--]C/Threads.h0
-rwxr-xr-x[-rw-r--r--]C/Util/7z/7z.dsp0
-rwxr-xr-x[-rw-r--r--]C/Util/7z/7z.dsw0
-rwxr-xr-x[-rw-r--r--]C/Util/7z/7zMain.c0
-rwxr-xr-x[-rw-r--r--]C/Util/7z/Precomp.c0
-rwxr-xr-x[-rw-r--r--]C/Util/7z/Precomp.h0
-rwxr-xr-x[-rw-r--r--]C/Util/7z/makefile0
-rwxr-xr-x[-rw-r--r--]C/Util/7z/makefile.gcc0
-rwxr-xr-x[-rw-r--r--]C/Util/7zipInstall/7zip.icobin1078 -> 1078 bytes
-rwxr-xr-x[-rw-r--r--]C/Util/7zipInstall/7zipInstall.c0
-rwxr-xr-x[-rw-r--r--]C/Util/7zipInstall/7zipInstall.dsp0
-rwxr-xr-x[-rw-r--r--]C/Util/7zipInstall/7zipInstall.dsw0
-rwxr-xr-x[-rw-r--r--]C/Util/7zipInstall/7zipInstall.manifest0
-rwxr-xr-x[-rw-r--r--]C/Util/7zipInstall/Precomp.c0
-rwxr-xr-x[-rw-r--r--]C/Util/7zipInstall/Precomp.h0
-rwxr-xr-x[-rw-r--r--]C/Util/7zipInstall/makefile0
-rwxr-xr-x[-rw-r--r--]C/Util/7zipInstall/resource.h0
-rwxr-xr-x[-rw-r--r--]C/Util/7zipInstall/resource.rc0
-rwxr-xr-x[-rw-r--r--]C/Util/7zipUninstall/7zipUninstall.c0
-rwxr-xr-x[-rw-r--r--]C/Util/7zipUninstall/7zipUninstall.dsp0
-rwxr-xr-x[-rw-r--r--]C/Util/7zipUninstall/7zipUninstall.dsw0
-rwxr-xr-x[-rw-r--r--]C/Util/7zipUninstall/7zipUninstall.icobin1078 -> 1078 bytes
-rwxr-xr-x[-rw-r--r--]C/Util/7zipUninstall/7zipUninstall.manifest0
-rwxr-xr-x[-rw-r--r--]C/Util/7zipUninstall/Precomp.c0
-rwxr-xr-x[-rw-r--r--]C/Util/7zipUninstall/Precomp.h0
-rwxr-xr-x[-rw-r--r--]C/Util/7zipUninstall/makefile0
-rwxr-xr-x[-rw-r--r--]C/Util/7zipUninstall/resource.h0
-rwxr-xr-x[-rw-r--r--]C/Util/7zipUninstall/resource.rc0
-rwxr-xr-x[-rw-r--r--]C/Util/Lzma/LzmaUtil.c0
-rwxr-xr-x[-rw-r--r--]C/Util/Lzma/LzmaUtil.dsp0
-rwxr-xr-x[-rw-r--r--]C/Util/Lzma/LzmaUtil.dsw0
-rwxr-xr-x[-rw-r--r--]C/Util/Lzma/makefile0
-rwxr-xr-x[-rw-r--r--]C/Util/Lzma/makefile.gcc0
-rwxr-xr-x[-rw-r--r--]C/Util/LzmaLib/LzmaLib.def0
-rwxr-xr-x[-rw-r--r--]C/Util/LzmaLib/LzmaLib.dsp0
-rwxr-xr-x[-rw-r--r--]C/Util/LzmaLib/LzmaLib.dsw0
-rwxr-xr-x[-rw-r--r--]C/Util/LzmaLib/LzmaLibExports.c0
-rwxr-xr-x[-rw-r--r--]C/Util/LzmaLib/makefile0
-rwxr-xr-x[-rw-r--r--]C/Util/LzmaLib/resource.rc0
-rwxr-xr-x[-rw-r--r--]C/Util/SfxSetup/Precomp.c0
-rwxr-xr-x[-rw-r--r--]C/Util/SfxSetup/Precomp.h0
-rwxr-xr-x[-rw-r--r--]C/Util/SfxSetup/SfxSetup.c0
-rwxr-xr-x[-rw-r--r--]C/Util/SfxSetup/SfxSetup.dsp0
-rwxr-xr-x[-rw-r--r--]C/Util/SfxSetup/SfxSetup.dsw0
-rwxr-xr-x[-rw-r--r--]C/Util/SfxSetup/makefile0
-rwxr-xr-x[-rw-r--r--]C/Util/SfxSetup/makefile_con0
-rwxr-xr-x[-rw-r--r--]C/Util/SfxSetup/resource.rc0
-rwxr-xr-x[-rw-r--r--]C/Util/SfxSetup/setup.icobin1078 -> 1078 bytes
-rwxr-xr-x[-rw-r--r--]C/Xz.c0
-rwxr-xr-x[-rw-r--r--]C/Xz.h0
-rwxr-xr-x[-rw-r--r--]C/XzCrc64.c0
-rwxr-xr-x[-rw-r--r--]C/XzCrc64.h0
-rwxr-xr-x[-rw-r--r--]C/XzCrc64Opt.c0
-rwxr-xr-x[-rw-r--r--]C/XzDec.c0
-rwxr-xr-x[-rw-r--r--]C/XzEnc.c0
-rwxr-xr-x[-rw-r--r--]C/XzEnc.h0
-rwxr-xr-x[-rw-r--r--]C/XzIn.c0
-rwxr-xr-x[-rw-r--r--]C/var_clang.mak0
-rwxr-xr-x[-rw-r--r--]C/var_clang_arm64.mak0
-rwxr-xr-x[-rw-r--r--]C/var_clang_x64.mak0
-rwxr-xr-x[-rw-r--r--]C/var_clang_x86.mak0
-rwxr-xr-x[-rw-r--r--]C/var_gcc.mak0
-rwxr-xr-x[-rw-r--r--]C/var_gcc_arm64.mak0
-rwxr-xr-x[-rw-r--r--]C/var_gcc_x64.mak0
-rwxr-xr-x[-rw-r--r--]C/var_gcc_x86.mak0
-rwxr-xr-x[-rw-r--r--]C/var_mac_arm64.mak0
-rwxr-xr-x[-rw-r--r--]C/var_mac_x64.mak0
-rwxr-xr-x[-rw-r--r--]C/warn_clang.mak0
-rwxr-xr-x[-rw-r--r--]C/warn_clang_mac.mak0
-rwxr-xr-x[-rw-r--r--]C/warn_gcc.mak0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/7zip.mak0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/7zip_gcc.mak8
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Aes.mak0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/7z/7z.dsp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/7z/7z.dsw0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/7z/7zCompressionMode.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/7z/7zCompressionMode.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/7z/7zDecode.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/7z/7zDecode.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/7z/7zEncode.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/7z/7zEncode.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/7z/7zExtract.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/7z/7zFolderInStream.cpp123
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/7z/7zFolderInStream.h31
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/7z/7zHandler.cpp2
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/7z/7zHandler.h5
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/7z/7zHandlerOut.cpp39
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/7z/7zHeader.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/7z/7zHeader.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/7z/7zIn.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/7z/7zIn.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/7z/7zItem.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/7z/7zOut.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/7z/7zOut.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/7z/7zProperties.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/7z/7zProperties.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/7z/7zRegister.cpp10
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/7z/7zSpecStream.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/7z/7zSpecStream.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/7z/7zUpdate.cpp141
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/7z/7zUpdate.h14
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/7z/StdAfx.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/7z/StdAfx.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/7z/makefile0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/7z/resource.rc0
-rwxr-xr-xCPP/7zip/Archive/ApfsHandler.cpp3546
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/ApmHandler.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/ArHandler.cpp14
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Archive.def0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Archive2.def0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/ArchiveExports.cpp1
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/ArjHandler.cpp10
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Base64Handler.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Bz2Handler.cpp100
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Cab/CabBlockInStream.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Cab/CabBlockInStream.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Cab/CabHandler.cpp10
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Cab/CabHandler.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Cab/CabHeader.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Cab/CabHeader.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Cab/CabIn.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Cab/CabIn.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Cab/CabItem.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Cab/CabRegister.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Cab/StdAfx.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Chm/ChmHandler.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Chm/ChmHandler.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Chm/ChmIn.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Chm/ChmIn.h11
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Chm/StdAfx.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/ComHandler.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Common/CoderMixer2.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Common/CoderMixer2.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Common/DummyOutStream.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Common/DummyOutStream.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Common/FindSignature.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Common/FindSignature.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Common/HandlerOut.cpp77
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Common/HandlerOut.h26
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Common/InStreamWithCRC.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Common/InStreamWithCRC.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Common/ItemNameUtils.cpp23
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Common/ItemNameUtils.h2
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Common/MultiStream.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Common/MultiStream.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Common/OutStreamWithCRC.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Common/OutStreamWithCRC.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Common/OutStreamWithSha1.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Common/OutStreamWithSha1.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Common/ParseProperties.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Common/ParseProperties.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Common/StdAfx.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/CpioHandler.cpp6
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/CramfsHandler.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/DeflateProps.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/DeflateProps.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/DllExports.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/DllExports2.cpp18
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/DmgHandler.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/ElfHandler.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/ExtHandler.cpp51
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/FatHandler.cpp15
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/FlvHandler.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/GptHandler.cpp75
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/GzHandler.cpp217
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/HandlerCont.cpp55
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/HandlerCont.h12
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/HfsHandler.cpp21
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/IArchive.h89
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Icons/7z.icobin4710 -> 4710 bytes
-rwxr-xr-xCPP/7zip/Archive/Icons/apfs.icobin0 -> 3638 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Icons/arj.icobin3638 -> 3638 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Icons/bz2.icobin3638 -> 3638 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Icons/cab.icobin3638 -> 3638 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Icons/cpio.icobin3638 -> 3638 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Icons/deb.icobin3638 -> 3638 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Icons/dmg.icobin3638 -> 3638 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Icons/fat.icobin3638 -> 3638 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Icons/gz.icobin3638 -> 3638 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Icons/hfs.icobin3638 -> 3638 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Icons/iso.icobin3638 -> 3638 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Icons/lzh.icobin3638 -> 3638 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Icons/lzma.icobin3638 -> 3638 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Icons/ntfs.icobin3638 -> 3638 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Icons/rar.icobin3638 -> 3638 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Icons/rpm.icobin3638 -> 3638 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Icons/split.icobin3638 -> 3638 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Icons/squashfs.icobin3638 -> 3638 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Icons/tar.icobin3638 -> 3638 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Icons/vhd.icobin3638 -> 3638 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Icons/wim.icobin3638 -> 3638 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Icons/xar.icobin3638 -> 3638 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Icons/xz.icobin3638 -> 3638 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Icons/z.icobin3638 -> 3638 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Icons/zip.icobin3638 -> 3638 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/IhexHandler.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Iso/IsoHandler.cpp24
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Iso/IsoHandler.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Iso/IsoHeader.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Iso/IsoHeader.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Iso/IsoIn.cpp2
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Iso/IsoIn.h15
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Iso/IsoItem.h13
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Iso/IsoRegister.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Iso/StdAfx.h0
-rwxr-xr-xCPP/7zip/Archive/LpHandler.cpp1173
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/LzhHandler.cpp15
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/LzmaHandler.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/MachoHandler.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/MbrHandler.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/MslzHandler.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/MubHandler.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Nsis/NsisDecode.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Nsis/NsisDecode.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Nsis/NsisHandler.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Nsis/NsisHandler.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Nsis/NsisIn.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Nsis/NsisIn.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Nsis/NsisRegister.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Nsis/StdAfx.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/NtfsHandler.cpp7
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/PeHandler.cpp6
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/PpmdHandler.cpp2
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/QcowHandler.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Rar/Rar5Handler.cpp44
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Rar/Rar5Handler.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Rar/RarHandler.cpp41
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Rar/RarHandler.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Rar/RarHeader.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Rar/RarItem.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Rar/RarVol.h17
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Rar/StdAfx.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Rar/StdAfx.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/RpmHandler.cpp6
-rwxr-xr-xCPP/7zip/Archive/SparseHandler.cpp548
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/SplitHandler.cpp7
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/SquashfsHandler.cpp155
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/StdAfx.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/SwfHandler.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Tar/StdAfx.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Tar/TarHandler.cpp445
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Tar/TarHandler.h27
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Tar/TarHandlerOut.cpp209
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Tar/TarHeader.cpp77
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Tar/TarHeader.h8
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Tar/TarIn.cpp945
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Tar/TarIn.h130
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Tar/TarItem.h246
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Tar/TarOut.cpp561
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Tar/TarOut.h31
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Tar/TarRegister.cpp16
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Tar/TarUpdate.cpp406
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Tar/TarUpdate.h39
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Udf/StdAfx.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Udf/UdfHandler.cpp20
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Udf/UdfHandler.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Udf/UdfIn.cpp2
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Udf/UdfIn.h2
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/UefiHandler.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/VdiHandler.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/VhdHandler.cpp3
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/VhdxHandler.cpp28
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/VmdkHandler.cpp2
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Wim/StdAfx.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Wim/WimHandler.cpp3
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Wim/WimHandler.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Wim/WimHandlerOut.cpp14
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Wim/WimIn.cpp9
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Wim/WimIn.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Wim/WimRegister.cpp21
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/XarHandler.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/XzHandler.cpp43
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/XzHandler.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/ZHandler.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Zip/StdAfx.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Zip/ZipAddCommon.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Zip/ZipAddCommon.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Zip/ZipCompressionMode.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Zip/ZipHandler.cpp178
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Zip/ZipHandler.h7
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Zip/ZipHandlerOut.cpp81
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Zip/ZipHeader.h9
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Zip/ZipIn.cpp23
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Zip/ZipIn.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Zip/ZipItem.cpp68
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Zip/ZipItem.h5
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Zip/ZipOut.cpp86
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Zip/ZipOut.h9
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Zip/ZipRegister.cpp18
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Zip/ZipUpdate.cpp171
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Zip/ZipUpdate.h28
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/makefile0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Asm.mak0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Alone/Alone.dsp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Alone/Alone.dsw0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Alone/StdAfx.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Alone/StdAfx.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Alone/afxres.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Alone/makefile0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Alone/makefile.gcc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Alone/resource.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Alone2/StdAfx.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Alone2/StdAfx.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Alone2/makefile1
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Alone2/makefile.gcc1
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Alone2/resource.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Alone7z/Alone.dsp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Alone7z/Alone.dsw0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Alone7z/StdAfx.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Alone7z/StdAfx.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Alone7z/makefile0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Alone7z/makefile.gcc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Alone7z/resource.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Fm/FM.dsp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Fm/FM.dsw0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Fm/StdAfx.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Fm/StdAfx.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Fm/makefile1
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Fm/resource.rc2
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Format7z/StdAfx.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Format7z/StdAfx.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Format7z/makefile0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Format7z/resource.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Format7zExtract/StdAfx.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Format7zExtract/StdAfx.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Format7zExtract/makefile0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Format7zExtract/resource.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Format7zExtractR/StdAfx.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Format7zExtractR/StdAfx.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Format7zExtractR/makefile0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Format7zExtractR/resource.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Format7zF/Arc.mak4
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Format7zF/Arc_gcc.mak4
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Format7zF/Format7z.dsp20
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Format7zF/Format7z.dsw0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Format7zF/StdAfx.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Format7zF/StdAfx.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Format7zF/makefile0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Format7zF/makefile.gcc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Format7zF/resource.rc3
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Format7zR/StdAfx.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Format7zR/StdAfx.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Format7zR/makefile0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/Format7zR/resource.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp2
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/LzmaCon/LzmaCon.dsp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/LzmaCon/LzmaCon.dsw0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/LzmaCon/StdAfx.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/LzmaCon/StdAfx.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/LzmaCon/makefile0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/LzmaCon/makefile.gcc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/LzmaCon/resource.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/SFXCon/7z.icobin1078 -> 1078 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/SFXCon/SFXCon.dsp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/SFXCon/SFXCon.dsw0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/SFXCon/SfxCon.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/SFXCon/StdAfx.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/SFXCon/StdAfx.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/SFXCon/makefile0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/SFXCon/makefile.gcc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/SFXCon/resource.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/SFXSetup/ExtractEngine.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/SFXSetup/SFXSetup.dsw0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/SFXSetup/StdAfx.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/SFXSetup/StdAfx.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/SFXSetup/makefile0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/SFXSetup/resource.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/SFXSetup/resource.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/SFXSetup/setup.icobin1078 -> 1078 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/SFXWin/7z.icobin1078 -> 1078 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/SFXWin/SFXWin.dsp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/SFXWin/SFXWin.dsw0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/SFXWin/SfxWin.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/SFXWin/StdAfx.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/SFXWin/StdAfx.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/SFXWin/makefile0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/SFXWin/resource.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/SFXWin/resource.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Bundles/makefile0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/CWrappers.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/CWrappers.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/CreateCoder.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/CreateCoder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/FilePathAutoRename.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/FilePathAutoRename.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/FileStreams.cpp292
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/FileStreams.h42
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/FilterCoder.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/FilterCoder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/InBuffer.cpp3
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/InBuffer.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/InOutTempBuffer.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/InOutTempBuffer.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/LimitedStreams.cpp68
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/LimitedStreams.h21
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/LockedStream.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/LockedStream.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/MemBlocks.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/MemBlocks.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/MethodId.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/MethodId.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/MethodProps.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/MethodProps.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/OffsetStream.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/OffsetStream.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/OutBuffer.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/OutBuffer.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/OutMemStream.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/OutMemStream.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/ProgressMt.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/ProgressMt.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/ProgressUtils.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/ProgressUtils.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/PropId.cpp9
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/RegisterArc.h24
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/RegisterCodec.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/StdAfx.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/StreamBinder.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/StreamBinder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/StreamObjects.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/StreamObjects.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/StreamUtils.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/StreamUtils.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/UniqBlocks.cpp8
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/UniqBlocks.h19
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/VirtThread.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Common/VirtThread.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/BZip2Const.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/BZip2Crc.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/BZip2Crc.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/BZip2Decoder.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/BZip2Decoder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/BZip2Encoder.cpp23
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/BZip2Encoder.h6
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/BZip2Register.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/Bcj2Coder.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/Bcj2Coder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/Bcj2Register.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/BcjCoder.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/BcjCoder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/BcjRegister.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/BitlDecoder.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/BitlDecoder.h4
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/BitlEncoder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/BitmDecoder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/BitmEncoder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/BranchMisc.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/BranchMisc.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/BranchRegister.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/ByteSwap.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/Codec.def0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/CodecExports.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/CopyCoder.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/CopyCoder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/CopyRegister.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/Deflate64Register.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/DeflateConst.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/DeflateDecoder.cpp1
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/DeflateDecoder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/DeflateEncoder.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/DeflateEncoder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/DeflateRegister.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/DeltaFilter.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/DllExports2Compress.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/DllExportsCompress.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/HuffmanDecoder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/ImplodeDecoder.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/ImplodeDecoder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/ImplodeHuffmanDecoder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/LzOutWindow.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/LzOutWindow.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/LzfseDecoder.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/LzfseDecoder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/LzhDecoder.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/LzhDecoder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/Lzma2Decoder.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/Lzma2Decoder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/Lzma2Encoder.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/Lzma2Encoder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/Lzma2Register.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/LzmaDecoder.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/LzmaDecoder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/LzmaEncoder.cpp7
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/LzmaEncoder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/LzmaRegister.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/LzmsDecoder.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/LzmsDecoder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/Lzx.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/LzxDecoder.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/LzxDecoder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/Mtf8.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/PpmdDecoder.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/PpmdDecoder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/PpmdEncoder.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/PpmdEncoder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/PpmdRegister.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/PpmdZip.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/PpmdZip.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/QuantumDecoder.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/QuantumDecoder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/Rar1Decoder.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/Rar1Decoder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/Rar2Decoder.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/Rar2Decoder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/Rar3Decoder.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/Rar3Decoder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/Rar3Vm.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/Rar3Vm.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/Rar5Decoder.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/Rar5Decoder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/RarCodecsRegister.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/ShrinkDecoder.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/ShrinkDecoder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/StdAfx.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/XpressDecoder.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/XpressDecoder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/XzDecoder.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/XzDecoder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/XzEncoder.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/XzEncoder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/ZDecoder.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/ZDecoder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/ZlibDecoder.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/ZlibDecoder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/ZlibEncoder.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/ZlibEncoder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Compress/makefile0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Crc.mak0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Crc64.mak0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Crypto/7zAes.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Crypto/7zAes.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Crypto/7zAesRegister.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Crypto/Codec.def0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Crypto/HmacSha1.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Crypto/HmacSha1.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Crypto/HmacSha256.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Crypto/HmacSha256.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Crypto/MyAes.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Crypto/MyAes.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Crypto/MyAesReg.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Crypto/Pbkdf2HmacSha1.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Crypto/RandGen.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Crypto/RandGen.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Crypto/Rar20Crypto.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Crypto/Rar20Crypto.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Crypto/Rar5Aes.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Crypto/Rar5Aes.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Crypto/RarAes.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Crypto/RarAes.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Crypto/Sha1Cls.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Crypto/StdAfx.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Crypto/WzAes.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Crypto/WzAes.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Crypto/ZipCrypto.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Crypto/ZipCrypto.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Crypto/ZipStrong.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Crypto/ZipStrong.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/GuiCommon.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Guid.txt8
-rwxr-xr-x[-rw-r--r--]CPP/7zip/ICoder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/IDecl.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/IPassword.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/IProgress.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/IStream.h7
-rwxr-xr-x[-rw-r--r--]CPP/7zip/LzFindOpt.mak0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/LzmaDec.mak0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/LzmaDec_gcc.mak0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/MyVersion.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/MyVersionInfo.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/PropID.h48
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Sha1.mak0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Sha256.mak0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/SubBuild.mak0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Agent/Agent.cpp65
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Agent/Agent.h8
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Agent/AgentOut.cpp53
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Agent/AgentProxy.cpp101
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Agent/AgentProxy.h6
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Agent/ArchiveFolder.cpp6
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Agent/ArchiveFolderOut.cpp8
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Agent/IFolderArchive.h9
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Agent/StdAfx.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Agent/UpdateCallbackAgent.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Client7z/Client7z.cpp198
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Client7z/Client7z.dsp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Client7z/Client7z.dsw0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Client7z/StdAfx.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Client7z/StdAfx.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Client7z/makefile0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Client7z/makefile.gcc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Client7z/resource.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/ArchiveCommandLine.cpp36
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/ArchiveCommandLine.h7
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/ArchiveExtractCallback.cpp315
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/ArchiveExtractCallback.h97
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/ArchiveName.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/ArchiveName.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/ArchiveOpenCallback.cpp12
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/ArchiveOpenCallback.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/Bench.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/Bench.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/CompressCall.cpp7
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/CompressCall.h2
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/CompressCall2.cpp28
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/DefaultName.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/DefaultName.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/DirItem.h249
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/EnumDirItems.cpp242
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/EnumDirItems.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/ExitCode.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/Extract.cpp55
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/Extract.h4
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/ExtractMode.h10
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/ExtractingFilePath.cpp11
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/ExtractingFilePath.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/HashCalc.cpp85
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/HashCalc.h6
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/IFileExtractCallback.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/LoadCodecs.cpp48
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/LoadCodecs.h40
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/OpenArchive.cpp166
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/OpenArchive.h42
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/PropIDUtils.cpp51
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/PropIDUtils.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/Property.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/SetProperties.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/SetProperties.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/SortUtils.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/SortUtils.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/StdAfx.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/TempFiles.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/TempFiles.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/Update.cpp205
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/Update.h3
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/UpdateAction.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/UpdateAction.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/UpdateCallback.cpp205
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/UpdateCallback.h27
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/UpdatePair.cpp125
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/UpdatePair.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/UpdateProduce.cpp2
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/UpdateProduce.h4
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/WorkDir.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/WorkDir.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/ZipRegistry.cpp105
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Common/ZipRegistry.h47
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Console/BenchCon.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Console/BenchCon.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Console/Console.dsp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Console/Console.dsw0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Console/Console.mak0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Console/Console.manifest0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Console/ConsoleClose.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Console/ConsoleClose.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Console/ExtractCallbackConsole.cpp7
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Console/ExtractCallbackConsole.h21
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Console/HashCon.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Console/HashCon.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Console/List.cpp72
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Console/List.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Console/Main.cpp32
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Console/MainAr.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Console/OpenCallbackConsole.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Console/OpenCallbackConsole.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Console/PercentPrinter.cpp3
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Console/PercentPrinter.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Console/StdAfx.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Console/StdAfx.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Console/UpdateCallbackConsole.cpp169
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Console/UpdateCallbackConsole.h5
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Console/UserInputUtils.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Console/UserInputUtils.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Console/makefile0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Console/makefile.gcc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Console/resource.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Explorer/7-zip.dll.manifest0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Explorer/ContextMenu.cpp5
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Explorer/ContextMenu.h1
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Explorer/ContextMenuFlags.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Explorer/DllExportsExplorer.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Explorer/Explorer.def0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Explorer/Explorer.dsp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Explorer/Explorer.dsw0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Explorer/MenuLogo.bmpbin114 -> 114 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Explorer/MyExplorerCommand.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Explorer/MyMessages.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Explorer/MyMessages.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Explorer/RegistryContextMenu.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Explorer/RegistryContextMenu.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Explorer/StdAfx.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Explorer/StdAfx.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Explorer/makefile0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Explorer/resource.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Explorer/resource.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Explorer/resource2.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Far/ExtractEngine.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Far/ExtractEngine.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Far/Far.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Far/Far.def0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Far/Far.dsp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Far/Far.dsw0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Far/FarPlugin.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Far/FarUtils.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Far/FarUtils.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Far/Messages.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Far/OverwriteDialogFar.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Far/OverwriteDialogFar.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Far/Plugin.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Far/Plugin.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Far/PluginCommon.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Far/PluginDelete.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Far/PluginRead.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Far/PluginWrite.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Far/ProgressBox.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Far/ProgressBox.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Far/StdAfx.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Far/StdAfx.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Far/UpdateCallbackFar.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Far/UpdateCallbackFar.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Far/makefile0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/Far/resource.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/7zFM.exe.manifest0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/7zipLogo.icobin9150 -> 9150 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/AboutDialog.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/AboutDialog.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/AboutDialog.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/AboutDialogRes.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/Add.bmpbin982 -> 982 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/Add2.bmpbin406 -> 406 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/AltStreamsFolder.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/AltStreamsFolder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/App.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/App.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/AppState.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/BrowseDialog.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/BrowseDialog.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/BrowseDialog.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/BrowseDialogRes.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/ClassDefs.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/ComboDialog.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/ComboDialog.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/ComboDialog.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/ComboDialogRes.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/Copy.bmpbin982 -> 982 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/Copy2.bmpbin406 -> 406 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/CopyDialog.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/CopyDialog.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/CopyDialog.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/CopyDialogRes.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/Delete.bmpbin982 -> 982 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/Delete2.bmpbin406 -> 406 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/DialogSize.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/EditDialog.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/EditDialog.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/EditDialog.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/EditDialogRes.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/EditPage.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/EditPage.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/EditPage.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/EditPage2.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/EditPageRes.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/EnumFormatEtc.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/EnumFormatEtc.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/Extract.bmpbin982 -> 982 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/Extract2.bmpbin406 -> 406 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/ExtractCallback.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/ExtractCallback.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/FM.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/FM.dsp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/FM.dsw0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/FM.icobin4846 -> 4846 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/FM.mak0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/FSDrives.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/FSDrives.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/FSFolder.cpp105
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/FSFolder.h5
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/FSFolderCopy.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/FileFolderPluginOpen.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/FilePlugins.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/FilePlugins.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/FoldersPage.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/FoldersPage.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/FoldersPage.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/FoldersPage2.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/FoldersPageRes.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/FormatUtils.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/FormatUtils.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/HelpUtils.cpp42
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/HelpUtils.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/IFolder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/Info.bmpbin982 -> 982 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/Info2.bmpbin406 -> 406 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/LangPage.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/LangPage.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/LangPage.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/LangPageRes.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/LangUtils.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/LangUtils.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/LinkDialog.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/LinkDialog.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/LinkDialog.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/LinkDialogRes.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/ListViewDialog.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/ListViewDialog.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/ListViewDialog.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/ListViewDialogRes.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/MenuPage.cpp76
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/MenuPage.h5
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/MenuPage.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/MenuPage2.rc15
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/MenuPageRes.h4
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/MessagesDialog.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/MessagesDialog.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/MessagesDialog.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/MessagesDialogRes.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/Move.bmpbin982 -> 982 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/Move2.bmpbin406 -> 406 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/MyCom2.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/MyLoadMenu.cpp3
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/MyLoadMenu.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/MyWindowsNew.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/NetFolder.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/NetFolder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/OpenCallback.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/OpenCallback.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/OptionsDialog.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/OverwriteDialog.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/OverwriteDialog.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/OverwriteDialog.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/OverwriteDialogRes.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/Panel.cpp5
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/Panel.h5
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/PanelCopy.cpp21
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/PanelCrc.cpp1
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/PanelDrag.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/PanelFolderChange.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/PanelItemOpen.cpp19
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/PanelItems.cpp6
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/PanelKey.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/PanelListNotify.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/PanelMenu.cpp2
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/PanelOperations.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/PanelSelect.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/PanelSort.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/PanelSplitFile.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/PasswordDialog.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/PasswordDialog.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/PasswordDialog.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/PasswordDialogRes.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/PluginInterface.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/PluginLoader.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/ProgramLocation.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/ProgramLocation.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/ProgressDialog.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/ProgressDialog.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/ProgressDialog.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/ProgressDialog2.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/ProgressDialog2.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/ProgressDialog2.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/ProgressDialog2Res.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/ProgressDialog2a.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/ProgressDialogRes.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/PropertyName.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/PropertyName.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/PropertyName.rc7
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/PropertyNameRes.h7
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/RegistryAssociations.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/RegistryAssociations.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/RegistryPlugins.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/RegistryPlugins.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/RegistryUtils.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/RegistryUtils.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/RootFolder.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/RootFolder.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/SettingsPage.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/SettingsPage.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/SettingsPage.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/SettingsPage2.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/SettingsPageRes.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/SplitDialog.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/SplitDialog.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/SplitDialog.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/SplitDialogRes.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/SplitUtils.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/SplitUtils.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/StdAfx.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/StdAfx.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/StringUtils.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/StringUtils.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/SysIconUtils.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/SysIconUtils.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/SystemPage.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/SystemPage.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/SystemPage.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/SystemPageRes.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/Test.bmpbin982 -> 982 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/Test2.bmpbin406 -> 406 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/TextPairs.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/TextPairs.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/UpdateCallback100.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/UpdateCallback100.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/VerCtrl.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/ViewSettings.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/ViewSettings.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/makefile0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/resource.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/resource.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/resourceGui.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/FileManager/resourceGui.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/GUI/7zG.exe.manifest0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/GUI/BenchmarkDialog.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/GUI/BenchmarkDialog.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/GUI/BenchmarkDialog.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/GUI/BenchmarkDialogRes.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/GUI/CompressDialog.cpp724
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/GUI/CompressDialog.h168
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/GUI/CompressDialog.rc27
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/GUI/CompressDialogRes.h33
-rwxr-xr-xCPP/7zip/UI/GUI/CompressOptionsDialog.rc76
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/GUI/Extract.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/GUI/ExtractDialog.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/GUI/ExtractDialog.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/GUI/ExtractDialog.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/GUI/ExtractDialogRes.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/GUI/ExtractGUI.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/GUI/ExtractGUI.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/GUI/ExtractRes.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/GUI/FM.icobin4846 -> 4846 bytes
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/GUI/GUI.cpp4
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/GUI/GUI.dsp16
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/GUI/GUI.dsw0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/GUI/HashGUI.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/GUI/HashGUI.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/GUI/StdAfx.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/GUI/StdAfx.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/GUI/UpdateCallbackGUI.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/GUI/UpdateCallbackGUI2.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/GUI/UpdateCallbackGUI2.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/GUI/UpdateGUI.cpp182
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/GUI/UpdateGUI.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/GUI/makefile0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/GUI/resource.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/GUI/resource2.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/GUI/resource2.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/GUI/resource3.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/GUI/resource3.rc0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/UI/makefile0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/cmpl_clang.mak0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/cmpl_clang_arm64.mak0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/cmpl_clang_x64.mak0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/cmpl_clang_x86.mak0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/cmpl_gcc.mak0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/cmpl_gcc_arm64.mak0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/cmpl_gcc_x64.mak0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/cmpl_gcc_x86.mak0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/cmpl_mac_arm64.mak0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/cmpl_mac_x64.mak0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/makefile0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/var_clang.mak0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/var_clang_arm64.mak0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/var_clang_x64.mak0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/var_clang_x86.mak0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/var_gcc.mak0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/var_gcc_arm64.mak0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/var_gcc_x64.mak0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/var_gcc_x86.mak0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/var_mac_arm64.mak0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/var_mac_x64.mak0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/warn_clang.mak0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/warn_clang_mac.mak0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/warn_gcc.mak0
-rwxr-xr-x[-rw-r--r--]CPP/Build.mak0
-rwxr-xr-x[-rw-r--r--]CPP/Common/AutoPtr.h0
-rwxr-xr-x[-rw-r--r--]CPP/Common/CRC.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Common/C_FileIO.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Common/C_FileIO.h0
-rwxr-xr-x[-rw-r--r--]CPP/Common/CksumReg.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Common/ComTry.h0
-rwxr-xr-x[-rw-r--r--]CPP/Common/CommandLineParser.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Common/CommandLineParser.h0
-rwxr-xr-x[-rw-r--r--]CPP/Common/Common.h2
-rwxr-xr-x[-rw-r--r--]CPP/Common/CrcReg.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Common/Defs.h0
-rwxr-xr-x[-rw-r--r--]CPP/Common/DynLimBuf.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Common/DynLimBuf.h0
-rwxr-xr-x[-rw-r--r--]CPP/Common/DynamicBuffer.h0
-rwxr-xr-x[-rw-r--r--]CPP/Common/IntToString.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Common/IntToString.h0
-rwxr-xr-x[-rw-r--r--]CPP/Common/Lang.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Common/Lang.h0
-rwxr-xr-x[-rw-r--r--]CPP/Common/ListFileUtils.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Common/ListFileUtils.h0
-rwxr-xr-x[-rw-r--r--]CPP/Common/LzFindPrepare.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Common/MyBuffer.h0
-rwxr-xr-x[-rw-r--r--]CPP/Common/MyBuffer2.h0
-rwxr-xr-x[-rw-r--r--]CPP/Common/MyCom.h1
-rwxr-xr-x[-rw-r--r--]CPP/Common/MyException.h0
-rwxr-xr-x[-rw-r--r--]CPP/Common/MyGuidDef.h0
-rwxr-xr-x[-rw-r--r--]CPP/Common/MyInitGuid.h0
-rwxr-xr-x[-rw-r--r--]CPP/Common/MyLinux.h33
-rwxr-xr-x[-rw-r--r--]CPP/Common/MyMap.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Common/MyMap.h0
-rwxr-xr-x[-rw-r--r--]CPP/Common/MyString.cpp187
-rwxr-xr-x[-rw-r--r--]CPP/Common/MyString.h3
-rwxr-xr-x[-rw-r--r--]CPP/Common/MyTypes.h0
-rwxr-xr-x[-rw-r--r--]CPP/Common/MyUnknown.h0
-rwxr-xr-x[-rw-r--r--]CPP/Common/MyVector.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Common/MyVector.h215
-rwxr-xr-x[-rw-r--r--]CPP/Common/MyWindows.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Common/MyWindows.h2
-rwxr-xr-x[-rw-r--r--]CPP/Common/MyXml.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Common/MyXml.h0
-rwxr-xr-x[-rw-r--r--]CPP/Common/NewHandler.cpp19
-rwxr-xr-x[-rw-r--r--]CPP/Common/NewHandler.h0
-rwxr-xr-x[-rw-r--r--]CPP/Common/Random.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Common/Random.h0
-rwxr-xr-x[-rw-r--r--]CPP/Common/Sha1Prepare.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Common/Sha1Reg.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Common/Sha256Prepare.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Common/Sha256Reg.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Common/StdAfx.h0
-rwxr-xr-x[-rw-r--r--]CPP/Common/StdInStream.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Common/StdInStream.h0
-rwxr-xr-x[-rw-r--r--]CPP/Common/StdOutStream.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Common/StdOutStream.h0
-rwxr-xr-x[-rw-r--r--]CPP/Common/StringConvert.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Common/StringConvert.h0
-rwxr-xr-x[-rw-r--r--]CPP/Common/StringToInt.cpp27
-rwxr-xr-x[-rw-r--r--]CPP/Common/StringToInt.h1
-rwxr-xr-x[-rw-r--r--]CPP/Common/TextConfig.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Common/TextConfig.h0
-rwxr-xr-x[-rw-r--r--]CPP/Common/UTFConvert.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Common/UTFConvert.h0
-rwxr-xr-x[-rw-r--r--]CPP/Common/Wildcard.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Common/Wildcard.h0
-rwxr-xr-x[-rw-r--r--]CPP/Common/XzCrc64Init.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Common/XzCrc64Reg.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/COM.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/COM.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/Clipboard.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/Clipboard.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/CommonDialog.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/CommonDialog.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/Console.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/Console.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/Control/ComboBox.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/Control/ComboBox.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/Control/CommandBar.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/Control/Dialog.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/Control/Dialog.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/Control/Edit.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/Control/ImageList.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/Control/ImageList.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/Control/ListView.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/Control/ListView.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/Control/ProgressBar.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/Control/PropertyPage.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/Control/PropertyPage.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/Control/ReBar.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/Control/Static.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/Control/StatusBar.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/Control/StdAfx.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/Control/ToolBar.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/Control/Trackbar.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/Control/Window2.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/Control/Window2.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/DLL.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/DLL.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/Defs.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/ErrorMsg.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/ErrorMsg.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/FileDir.cpp73
-rwxr-xr-x[-rw-r--r--]CPP/Windows/FileDir.h10
-rwxr-xr-x[-rw-r--r--]CPP/Windows/FileFind.cpp133
-rwxr-xr-x[-rw-r--r--]CPP/Windows/FileFind.h95
-rwxr-xr-x[-rw-r--r--]CPP/Windows/FileIO.cpp88
-rwxr-xr-x[-rw-r--r--]CPP/Windows/FileIO.h44
-rwxr-xr-x[-rw-r--r--]CPP/Windows/FileLink.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/FileMapping.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/FileMapping.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/FileName.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/FileName.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/FileSystem.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/FileSystem.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/Handle.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/MemoryGlobal.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/MemoryGlobal.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/MemoryLock.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/MemoryLock.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/Menu.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/Menu.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/NationalTime.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/NationalTime.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/Net.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/Net.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/NtCheck.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/ProcessMessages.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/ProcessMessages.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/ProcessUtils.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/ProcessUtils.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/PropVariant.cpp132
-rwxr-xr-x[-rw-r--r--]CPP/Windows/PropVariant.h52
-rwxr-xr-x[-rw-r--r--]CPP/Windows/PropVariantConv.cpp58
-rwxr-xr-x[-rw-r--r--]CPP/Windows/PropVariantConv.h5
-rwxr-xr-x[-rw-r--r--]CPP/Windows/PropVariantUtils.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/PropVariantUtils.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/Registry.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/Registry.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/ResourceString.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/ResourceString.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/SecurityUtils.cpp2
-rwxr-xr-x[-rw-r--r--]CPP/Windows/SecurityUtils.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/Shell.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/Shell.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/StdAfx.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/Synchronization.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/Synchronization.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/System.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/System.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/SystemInfo.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/SystemInfo.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/Thread.h0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/TimeUtils.cpp220
-rwxr-xr-x[-rw-r--r--]CPP/Windows/TimeUtils.h130
-rwxr-xr-x[-rw-r--r--]CPP/Windows/Window.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/Windows/Window.h0
-rwxr-xr-x[-rw-r--r--]DOC/7zC.txt0
-rwxr-xr-x[-rw-r--r--]DOC/7zFormat.txt0
-rwxr-xr-x[-rw-r--r--]DOC/7zip.hhp0
-rwxr-xr-x[-rw-r--r--]DOC/7zip.wxs4
-rwxr-xr-x[-rw-r--r--]DOC/License.txt0
-rwxr-xr-x[-rw-r--r--]DOC/Methods.txt0
-rwxr-xr-x[-rw-r--r--]DOC/copying.txt0
-rwxr-xr-x[-rw-r--r--]DOC/lzma.txt0
-rwxr-xr-x[-rw-r--r--]DOC/readme.txt0
-rwxr-xr-x[-rw-r--r--]DOC/src-history.txt6
-rwxr-xr-x[-rw-r--r--]DOC/unRarLicense.txt0
1248 files changed, 15196 insertions, 2397 deletions
diff --git a/Asm/arm/7zCrcOpt.asm b/Asm/arm/7zCrcOpt.asm
index 6001d8e3..6001d8e3 100644..100755
--- a/Asm/arm/7zCrcOpt.asm
+++ b/Asm/arm/7zCrcOpt.asm
diff --git a/Asm/arm64/7zAsm.S b/Asm/arm64/7zAsm.S
index 12e950b4..12e950b4 100644..100755
--- a/Asm/arm64/7zAsm.S
+++ b/Asm/arm64/7zAsm.S
diff --git a/Asm/arm64/LzmaDecOpt.S b/Asm/arm64/LzmaDecOpt.S
index 10dc4735..10dc4735 100644..100755
--- a/Asm/arm64/LzmaDecOpt.S
+++ b/Asm/arm64/LzmaDecOpt.S
diff --git a/Asm/x86/7zAsm.asm b/Asm/x86/7zAsm.asm
index 6275bb74..19c40dac 100644..100755
--- a/Asm/x86/7zAsm.asm
+++ b/Asm/x86/7zAsm.asm
@@ -1,7 +1,12 @@
; 7zAsm.asm -- ASM macros
-; 2021-12-25 : Igor Pavlov : Public domain
+; 2022-05-16 : Igor Pavlov : Public domain
+; UASM can require these changes
+; OPTION FRAMEPRESERVEFLAGS:ON
+; OPTION PROLOGUE:NONE
+; OPTION EPILOGUE:NONE
+
ifdef @wordsize
; @wordsize is defined only in JWASM and ASMC and is not defined in MASM
; @wordsize eq 8 for 64-bit x64
diff --git a/Asm/x86/7zCrcOpt.asm b/Asm/x86/7zCrcOpt.asm
index 0fee2064..0fee2064 100644..100755
--- a/Asm/x86/7zCrcOpt.asm
+++ b/Asm/x86/7zCrcOpt.asm
diff --git a/Asm/x86/AesOpt.asm b/Asm/x86/AesOpt.asm
index 84bf8977..84bf8977 100644..100755
--- a/Asm/x86/AesOpt.asm
+++ b/Asm/x86/AesOpt.asm
diff --git a/Asm/x86/LzFindOpt.asm b/Asm/x86/LzFindOpt.asm
index 42e10bda..42e10bda 100644..100755
--- a/Asm/x86/LzFindOpt.asm
+++ b/Asm/x86/LzFindOpt.asm
diff --git a/Asm/x86/LzmaDecOpt.asm b/Asm/x86/LzmaDecOpt.asm
index f2818e77..f2818e77 100644..100755
--- a/Asm/x86/LzmaDecOpt.asm
+++ b/Asm/x86/LzmaDecOpt.asm
diff --git a/Asm/x86/Sha1Opt.asm b/Asm/x86/Sha1Opt.asm
index 3495fd16..3495fd16 100644..100755
--- a/Asm/x86/Sha1Opt.asm
+++ b/Asm/x86/Sha1Opt.asm
diff --git a/Asm/x86/Sha256Opt.asm b/Asm/x86/Sha256Opt.asm
index 5d02c90a..3e9f6eda 100644..100755
--- a/Asm/x86/Sha256Opt.asm
+++ b/Asm/x86/Sha256Opt.asm
@@ -1,5 +1,5 @@
; Sha256Opt.asm -- SHA-256 optimized code for SHA-256 x86 hardware instructions
-; 2021-03-10 : Igor Pavlov : Public domain
+; 2022-04-17 : Igor Pavlov : Public domain
include 7zAsm.asm
@@ -54,14 +54,20 @@ ifndef x64
.686
.xmm
endif
-
+
+; jwasm-based assemblers for linux and linker from new versions of binutils
+; can generate incorrect code for load [ARRAY + offset] instructions.
+; 22.00: we load K_CONST offset to (rTable) register to avoid jwasm+binutils problem
+ rTable equ r0
+ ; rTable equ K_CONST
+
ifdef x64
rNum equ REG_ABI_PARAM_2
if (IS_LINUX eq 0)
LOCAL_SIZE equ (16 * 2)
endif
else
- rNum equ r0
+ rNum equ r3
LOCAL_SIZE equ (16 * 1)
endif
@@ -103,15 +109,18 @@ MY_PROLOG macro
movdqa [r4 + 16], xmm9
endif
else ; x86
+ push r3
+ push r5
+ mov r5, r4
+ NUM_PUSH_REGS equ 2
+ PARAM_OFFSET equ (REG_SIZE * (1 + NUM_PUSH_REGS))
if (IS_CDECL gt 0)
- mov rState, [r4 + REG_SIZE * 1]
- mov rData, [r4 + REG_SIZE * 2]
- mov rNum, [r4 + REG_SIZE * 3]
+ mov rState, [r4 + PARAM_OFFSET]
+ mov rData, [r4 + PARAM_OFFSET + REG_SIZE * 1]
+ mov rNum, [r4 + PARAM_OFFSET + REG_SIZE * 2]
else ; fastcall
- mov rNum, [r4 + REG_SIZE * 1]
+ mov rNum, [r4 + PARAM_OFFSET]
endif
- push r5
- mov r5, r4
and r4, -16
sub r4, LOCAL_SIZE
endif
@@ -129,6 +138,7 @@ MY_EPILOG macro
else ; x86
mov r4, r5
pop r5
+ pop r3
endif
MY_ENDP
endm
@@ -171,7 +181,7 @@ pre2 equ 2
RND4 macro k
- movdqa msg, xmmword ptr [K_CONST + (k) * 16]
+ movdqa msg, xmmword ptr [rTable + (k) * 16]
paddd msg, @CatStr(xmm, %(w_regs + ((k + 0) mod 4)))
MY_sha256rnds2 state0_N, state1_N
pshufd msg, msg, 0eH
@@ -210,6 +220,8 @@ endm
MY_PROC Sha256_UpdateBlocks_HW, 3
MY_PROLOG
+ lea rTable, [K_CONST]
+
cmp rNum, 0
je end_c
diff --git a/Asm/x86/XzCrc64Opt.asm b/Asm/x86/XzCrc64Opt.asm
index ad22cc2f..ad22cc2f 100644..100755
--- a/Asm/x86/XzCrc64Opt.asm
+++ b/Asm/x86/XzCrc64Opt.asm
diff --git a/C/7z.h b/C/7z.h
index 304f75ff..304f75ff 100644..100755
--- a/C/7z.h
+++ b/C/7z.h
diff --git a/C/7zAlloc.c b/C/7zAlloc.c
index c924a529..c924a529 100644..100755
--- a/C/7zAlloc.c
+++ b/C/7zAlloc.c
diff --git a/C/7zAlloc.h b/C/7zAlloc.h
index 44778f9b..44778f9b 100644..100755
--- a/C/7zAlloc.h
+++ b/C/7zAlloc.h
diff --git a/C/7zArcIn.c b/C/7zArcIn.c
index 0d9dec41..0d9dec41 100644..100755
--- a/C/7zArcIn.c
+++ b/C/7zArcIn.c
diff --git a/C/7zBuf.c b/C/7zBuf.c
index 8865c32a..8865c32a 100644..100755
--- a/C/7zBuf.c
+++ b/C/7zBuf.c
diff --git a/C/7zBuf.h b/C/7zBuf.h
index 81d1b5b6..81d1b5b6 100644..100755
--- a/C/7zBuf.h
+++ b/C/7zBuf.h
diff --git a/C/7zBuf2.c b/C/7zBuf2.c
index 20834741..20834741 100644..100755
--- a/C/7zBuf2.c
+++ b/C/7zBuf2.c
diff --git a/C/7zCrc.c b/C/7zCrc.c
index f186324d..f186324d 100644..100755
--- a/C/7zCrc.c
+++ b/C/7zCrc.c
diff --git a/C/7zCrc.h b/C/7zCrc.h
index 8fd57958..8fd57958 100644..100755
--- a/C/7zCrc.h
+++ b/C/7zCrc.h
diff --git a/C/7zCrcOpt.c b/C/7zCrcOpt.c
index 69fad9ca..69fad9ca 100644..100755
--- a/C/7zCrcOpt.c
+++ b/C/7zCrcOpt.c
diff --git a/C/7zDec.c b/C/7zDec.c
index fbfd016e..fbfd016e 100644..100755
--- a/C/7zDec.c
+++ b/C/7zDec.c
diff --git a/C/7zFile.c b/C/7zFile.c
index 13d2efa4..13d2efa4 100644..100755
--- a/C/7zFile.c
+++ b/C/7zFile.c
diff --git a/C/7zFile.h b/C/7zFile.h
index 788abb6b..788abb6b 100644..100755
--- a/C/7zFile.h
+++ b/C/7zFile.h
diff --git a/C/7zStream.c b/C/7zStream.c
index 28a14604..28a14604 100644..100755
--- a/C/7zStream.c
+++ b/C/7zStream.c
diff --git a/C/7zTypes.h b/C/7zTypes.h
index fe4fde3f..f7d70718 100644..100755
--- a/C/7zTypes.h
+++ b/C/7zTypes.h
@@ -1,5 +1,5 @@
/* 7zTypes.h -- Basic types
-2021-12-25 : Igor Pavlov : Public domain */
+2022-04-01 : Igor Pavlov : Public domain */
#ifndef __7Z_TYPES_H
#define __7Z_TYPES_H
@@ -133,10 +133,6 @@ typedef int WRes;
#define MY__E_ERROR_NEGATIVE_SEEK MY_HRESULT_FROM_errno_CONST_ERROR(EINVAL)
*/
-// gcc / clang : (sizeof(long) == sizeof(void*)) in 32/64 bits
-typedef long INT_PTR;
-typedef unsigned long UINT_PTR;
-
#define TEXT(quote) quote
#define FILE_ATTRIBUTE_READONLY 0x0001
@@ -520,6 +516,14 @@ struct ISzAlloc
#endif
+#define k_PropVar_TimePrec_0 0
+#define k_PropVar_TimePrec_Unix 1
+#define k_PropVar_TimePrec_DOS 2
+#define k_PropVar_TimePrec_HighPrec 3
+#define k_PropVar_TimePrec_Base 16
+#define k_PropVar_TimePrec_100ns (k_PropVar_TimePrec_Base + 7)
+#define k_PropVar_TimePrec_1ns (k_PropVar_TimePrec_Base + 9)
+
EXTERN_C_END
#endif
diff --git a/C/7zVersion.h b/C/7zVersion.h
index e9363d37..89fffd96 100644..100755
--- a/C/7zVersion.h
+++ b/C/7zVersion.h
@@ -1,7 +1,7 @@
-#define MY_VER_MAJOR 21
-#define MY_VER_MINOR 07
+#define MY_VER_MAJOR 22
+#define MY_VER_MINOR 00
#define MY_VER_BUILD 0
-#define MY_VERSION_NUMBERS "21.07"
+#define MY_VERSION_NUMBERS "22.00"
#define MY_VERSION MY_VERSION_NUMBERS
#ifdef MY_CPU_NAME
@@ -10,12 +10,12 @@
#define MY_VERSION_CPU MY_VERSION
#endif
-#define MY_DATE "2021-12-26"
+#define MY_DATE "2022-06-15"
#undef MY_COPYRIGHT
#undef MY_VERSION_COPYRIGHT_DATE
#define MY_AUTHOR_NAME "Igor Pavlov"
#define MY_COPYRIGHT_PD "Igor Pavlov : Public domain"
-#define MY_COPYRIGHT_CR "Copyright (c) 1999-2021 Igor Pavlov"
+#define MY_COPYRIGHT_CR "Copyright (c) 1999-2022 Igor Pavlov"
#ifdef USE_COPYRIGHT_CR
#define MY_COPYRIGHT MY_COPYRIGHT_CR
diff --git a/C/7zVersion.rc b/C/7zVersion.rc
index e520995d..e520995d 100644..100755
--- a/C/7zVersion.rc
+++ b/C/7zVersion.rc
diff --git a/C/7zip_gcc_c.mak b/C/7zip_gcc_c.mak
index e8844407..e8844407 100644..100755
--- a/C/7zip_gcc_c.mak
+++ b/C/7zip_gcc_c.mak
diff --git a/C/Aes.c b/C/Aes.c
index 27e32e62..27e32e62 100644..100755
--- a/C/Aes.c
+++ b/C/Aes.c
diff --git a/C/Aes.h b/C/Aes.h
index 2aa22564..2aa22564 100644..100755
--- a/C/Aes.h
+++ b/C/Aes.h
diff --git a/C/AesOpt.c b/C/AesOpt.c
index 8be8ff69..8be8ff69 100644..100755
--- a/C/AesOpt.c
+++ b/C/AesOpt.c
diff --git a/C/Alloc.c b/C/Alloc.c
index d1af76c5..d1af76c5 100644..100755
--- a/C/Alloc.c
+++ b/C/Alloc.c
diff --git a/C/Alloc.h b/C/Alloc.h
index 3be2041e..3be2041e 100644..100755
--- a/C/Alloc.h
+++ b/C/Alloc.h
diff --git a/C/Bcj2.c b/C/Bcj2.c
index c7b95670..c7b95670 100644..100755
--- a/C/Bcj2.c
+++ b/C/Bcj2.c
diff --git a/C/Bcj2.h b/C/Bcj2.h
index 8824080a..8824080a 100644..100755
--- a/C/Bcj2.h
+++ b/C/Bcj2.h
diff --git a/C/Bcj2Enc.c b/C/Bcj2Enc.c
index 682362a1..682362a1 100644..100755
--- a/C/Bcj2Enc.c
+++ b/C/Bcj2Enc.c
diff --git a/C/Blake2.h b/C/Blake2.h
index 14f3cb64..14f3cb64 100644..100755
--- a/C/Blake2.h
+++ b/C/Blake2.h
diff --git a/C/Blake2s.c b/C/Blake2s.c
index 3c56a8b8..3c56a8b8 100644..100755
--- a/C/Blake2s.c
+++ b/C/Blake2s.c
diff --git a/C/Bra.c b/C/Bra.c
index 3b854d9c..3b854d9c 100644..100755
--- a/C/Bra.c
+++ b/C/Bra.c
diff --git a/C/Bra.h b/C/Bra.h
index 855e37a6..855e37a6 100644..100755
--- a/C/Bra.h
+++ b/C/Bra.h
diff --git a/C/Bra86.c b/C/Bra86.c
index 10a0fbd1..10a0fbd1 100644..100755
--- a/C/Bra86.c
+++ b/C/Bra86.c
diff --git a/C/BraIA64.c b/C/BraIA64.c
index d1dbc62c..d1dbc62c 100644..100755
--- a/C/BraIA64.c
+++ b/C/BraIA64.c
diff --git a/C/BwtSort.c b/C/BwtSort.c
index 3eb57efa..3eb57efa 100644..100755
--- a/C/BwtSort.c
+++ b/C/BwtSort.c
diff --git a/C/BwtSort.h b/C/BwtSort.h
index 7e989a99..7e989a99 100644..100755
--- a/C/BwtSort.h
+++ b/C/BwtSort.h
diff --git a/C/Compiler.h b/C/Compiler.h
index a9816fa5..a9816fa5 100644..100755
--- a/C/Compiler.h
+++ b/C/Compiler.h
diff --git a/C/CpuArch.c b/C/CpuArch.c
index fa9afe39..fa9afe39 100644..100755
--- a/C/CpuArch.c
+++ b/C/CpuArch.c
diff --git a/C/CpuArch.h b/C/CpuArch.h
index 529d3a50..529d3a50 100644..100755
--- a/C/CpuArch.h
+++ b/C/CpuArch.h
diff --git a/C/Delta.c b/C/Delta.c
index c4a4499f..c4a4499f 100644..100755
--- a/C/Delta.c
+++ b/C/Delta.c
diff --git a/C/Delta.h b/C/Delta.h
index 2fa54ad6..2fa54ad6 100644..100755
--- a/C/Delta.h
+++ b/C/Delta.h
diff --git a/C/DllSecur.c b/C/DllSecur.c
index d81508c0..d81508c0 100644..100755
--- a/C/DllSecur.c
+++ b/C/DllSecur.c
diff --git a/C/DllSecur.h b/C/DllSecur.h
index 64ff26cd..64ff26cd 100644..100755
--- a/C/DllSecur.h
+++ b/C/DllSecur.h
diff --git a/C/HuffEnc.c b/C/HuffEnc.c
index f3c2996d..f3c2996d 100644..100755
--- a/C/HuffEnc.c
+++ b/C/HuffEnc.c
diff --git a/C/HuffEnc.h b/C/HuffEnc.h
index 92b6878d..92b6878d 100644..100755
--- a/C/HuffEnc.h
+++ b/C/HuffEnc.h
diff --git a/C/LzFind.c b/C/LzFind.c
index 1b73c284..1b73c284 100644..100755
--- a/C/LzFind.c
+++ b/C/LzFind.c
diff --git a/C/LzFind.h b/C/LzFind.h
index eea873ff..eea873ff 100644..100755
--- a/C/LzFind.h
+++ b/C/LzFind.h
diff --git a/C/LzFindMt.c b/C/LzFindMt.c
index 4e67fc3f..4e67fc3f 100644..100755
--- a/C/LzFindMt.c
+++ b/C/LzFindMt.c
diff --git a/C/LzFindMt.h b/C/LzFindMt.h
index 660b7244..660b7244 100644..100755
--- a/C/LzFindMt.h
+++ b/C/LzFindMt.h
diff --git a/C/LzFindOpt.c b/C/LzFindOpt.c
index 8ff006e0..8ff006e0 100644..100755
--- a/C/LzFindOpt.c
+++ b/C/LzFindOpt.c
diff --git a/C/LzHash.h b/C/LzHash.h
index 77b898cf..77b898cf 100644..100755
--- a/C/LzHash.h
+++ b/C/LzHash.h
diff --git a/C/Lzma2Dec.c b/C/Lzma2Dec.c
index ac970a84..ac970a84 100644..100755
--- a/C/Lzma2Dec.c
+++ b/C/Lzma2Dec.c
diff --git a/C/Lzma2Dec.h b/C/Lzma2Dec.h
index b8ddeac8..b8ddeac8 100644..100755
--- a/C/Lzma2Dec.h
+++ b/C/Lzma2Dec.h
diff --git a/C/Lzma2DecMt.c b/C/Lzma2DecMt.c
index 9f1dc52b..9f1dc52b 100644..100755
--- a/C/Lzma2DecMt.c
+++ b/C/Lzma2DecMt.c
diff --git a/C/Lzma2DecMt.h b/C/Lzma2DecMt.h
index 7791c310..7791c310 100644..100755
--- a/C/Lzma2DecMt.h
+++ b/C/Lzma2DecMt.h
diff --git a/C/Lzma2Enc.c b/C/Lzma2Enc.c
index e61a5dfe..e61a5dfe 100644..100755
--- a/C/Lzma2Enc.c
+++ b/C/Lzma2Enc.c
diff --git a/C/Lzma2Enc.h b/C/Lzma2Enc.h
index 6a6110ff..6a6110ff 100644..100755
--- a/C/Lzma2Enc.h
+++ b/C/Lzma2Enc.h
diff --git a/C/Lzma86.h b/C/Lzma86.h
index bebed5cb..bebed5cb 100644..100755
--- a/C/Lzma86.h
+++ b/C/Lzma86.h
diff --git a/C/Lzma86Dec.c b/C/Lzma86Dec.c
index 21031745..21031745 100644..100755
--- a/C/Lzma86Dec.c
+++ b/C/Lzma86Dec.c
diff --git a/C/Lzma86Enc.c b/C/Lzma86Enc.c
index 14fcd65c..14fcd65c 100644..100755
--- a/C/Lzma86Enc.c
+++ b/C/Lzma86Enc.c
diff --git a/C/LzmaDec.c b/C/LzmaDec.c
index d6742e5a..d6742e5a 100644..100755
--- a/C/LzmaDec.c
+++ b/C/LzmaDec.c
diff --git a/C/LzmaDec.h b/C/LzmaDec.h
index 6f129625..6f129625 100644..100755
--- a/C/LzmaDec.h
+++ b/C/LzmaDec.h
diff --git a/C/LzmaEnc.c b/C/LzmaEnc.c
index b04a7b7b..b04a7b7b 100644..100755
--- a/C/LzmaEnc.c
+++ b/C/LzmaEnc.c
diff --git a/C/LzmaEnc.h b/C/LzmaEnc.h
index bc2ed504..bc2ed504 100644..100755
--- a/C/LzmaEnc.h
+++ b/C/LzmaEnc.h
diff --git a/C/LzmaLib.c b/C/LzmaLib.c
index 706e9e58..706e9e58 100644..100755
--- a/C/LzmaLib.c
+++ b/C/LzmaLib.c
diff --git a/C/LzmaLib.h b/C/LzmaLib.h
index c343a859..c343a859 100644..100755
--- a/C/LzmaLib.h
+++ b/C/LzmaLib.h
diff --git a/C/MtCoder.c b/C/MtCoder.c
index 99dc9090..99dc9090 100644..100755
--- a/C/MtCoder.c
+++ b/C/MtCoder.c
diff --git a/C/MtCoder.h b/C/MtCoder.h
index 5a5f4d11..5a5f4d11 100644..100755
--- a/C/MtCoder.h
+++ b/C/MtCoder.h
diff --git a/C/MtDec.c b/C/MtDec.c
index 45a67139..45a67139 100644..100755
--- a/C/MtDec.c
+++ b/C/MtDec.c
diff --git a/C/MtDec.h b/C/MtDec.h
index c2da46ae..c2da46ae 100644..100755
--- a/C/MtDec.h
+++ b/C/MtDec.h
diff --git a/C/Ppmd.h b/C/Ppmd.h
index b1987920..b1987920 100644..100755
--- a/C/Ppmd.h
+++ b/C/Ppmd.h
diff --git a/C/Ppmd7.c b/C/Ppmd7.c
index cf401cb3..cf401cb3 100644..100755
--- a/C/Ppmd7.c
+++ b/C/Ppmd7.c
diff --git a/C/Ppmd7.h b/C/Ppmd7.h
index d31809ae..d31809ae 100644..100755
--- a/C/Ppmd7.h
+++ b/C/Ppmd7.h
diff --git a/C/Ppmd7Dec.c b/C/Ppmd7Dec.c
index 55d74ff9..55d74ff9 100644..100755
--- a/C/Ppmd7Dec.c
+++ b/C/Ppmd7Dec.c
diff --git a/C/Ppmd7Enc.c b/C/Ppmd7Enc.c
index 62139c5b..62139c5b 100644..100755
--- a/C/Ppmd7Enc.c
+++ b/C/Ppmd7Enc.c
diff --git a/C/Ppmd7aDec.c b/C/Ppmd7aDec.c
index c4245784..c4245784 100644..100755
--- a/C/Ppmd7aDec.c
+++ b/C/Ppmd7aDec.c
diff --git a/C/Ppmd8.c b/C/Ppmd8.c
index fda8b88a..fda8b88a 100644..100755
--- a/C/Ppmd8.c
+++ b/C/Ppmd8.c
diff --git a/C/Ppmd8.h b/C/Ppmd8.h
index fe93fe7c..fe93fe7c 100644..100755
--- a/C/Ppmd8.h
+++ b/C/Ppmd8.h
diff --git a/C/Ppmd8Dec.c b/C/Ppmd8Dec.c
index d205de28..d205de28 100644..100755
--- a/C/Ppmd8Dec.c
+++ b/C/Ppmd8Dec.c
diff --git a/C/Ppmd8Enc.c b/C/Ppmd8Enc.c
index 32ff8052..32ff8052 100644..100755
--- a/C/Ppmd8Enc.c
+++ b/C/Ppmd8Enc.c
diff --git a/C/Precomp.h b/C/Precomp.h
index e8ff8b40..e8ff8b40 100644..100755
--- a/C/Precomp.h
+++ b/C/Precomp.h
diff --git a/C/RotateDefs.h b/C/RotateDefs.h
index 8f01d1a6..8f01d1a6 100644..100755
--- a/C/RotateDefs.h
+++ b/C/RotateDefs.h
diff --git a/C/Sha1.c b/C/Sha1.c
index 9665b5b5..9665b5b5 100644..100755
--- a/C/Sha1.c
+++ b/C/Sha1.c
diff --git a/C/Sha1.h b/C/Sha1.h
index 345a816a..345a816a 100644..100755
--- a/C/Sha1.h
+++ b/C/Sha1.h
diff --git a/C/Sha1Opt.c b/C/Sha1Opt.c
index 63132da3..63132da3 100644..100755
--- a/C/Sha1Opt.c
+++ b/C/Sha1Opt.c
diff --git a/C/Sha256.c b/C/Sha256.c
index 8b3983ea..8b3983ea 100644..100755
--- a/C/Sha256.c
+++ b/C/Sha256.c
diff --git a/C/Sha256.h b/C/Sha256.h
index aa38501e..aa38501e 100644..100755
--- a/C/Sha256.h
+++ b/C/Sha256.h
diff --git a/C/Sha256Opt.c b/C/Sha256Opt.c
index decc1382..decc1382 100644..100755
--- a/C/Sha256Opt.c
+++ b/C/Sha256Opt.c
diff --git a/C/Sort.c b/C/Sort.c
index e1097e38..e1097e38 100644..100755
--- a/C/Sort.c
+++ b/C/Sort.c
diff --git a/C/Sort.h b/C/Sort.h
index 2e2963a2..2e2963a2 100644..100755
--- a/C/Sort.h
+++ b/C/Sort.h
diff --git a/C/Threads.c b/C/Threads.c
index 58eb90ff..58eb90ff 100644..100755
--- a/C/Threads.c
+++ b/C/Threads.c
diff --git a/C/Threads.h b/C/Threads.h
index 89ecb92b..89ecb92b 100644..100755
--- a/C/Threads.h
+++ b/C/Threads.h
diff --git a/C/Util/7z/7z.dsp b/C/Util/7z/7z.dsp
index be0f0a74..be0f0a74 100644..100755
--- a/C/Util/7z/7z.dsp
+++ b/C/Util/7z/7z.dsp
diff --git a/C/Util/7z/7z.dsw b/C/Util/7z/7z.dsw
index 848d13cb..848d13cb 100644..100755
--- a/C/Util/7z/7z.dsw
+++ b/C/Util/7z/7z.dsw
diff --git a/C/Util/7z/7zMain.c b/C/Util/7z/7zMain.c
index 9d555098..9d555098 100644..100755
--- a/C/Util/7z/7zMain.c
+++ b/C/Util/7z/7zMain.c
diff --git a/C/Util/7z/Precomp.c b/C/Util/7z/Precomp.c
index 01605e3c..01605e3c 100644..100755
--- a/C/Util/7z/Precomp.c
+++ b/C/Util/7z/Precomp.c
diff --git a/C/Util/7z/Precomp.h b/C/Util/7z/Precomp.h
index 588a66f7..588a66f7 100644..100755
--- a/C/Util/7z/Precomp.h
+++ b/C/Util/7z/Precomp.h
diff --git a/C/Util/7z/makefile b/C/Util/7z/makefile
index 9a49fd51..9a49fd51 100644..100755
--- a/C/Util/7z/makefile
+++ b/C/Util/7z/makefile
diff --git a/C/Util/7z/makefile.gcc b/C/Util/7z/makefile.gcc
index 4263d675..4263d675 100644..100755
--- a/C/Util/7z/makefile.gcc
+++ b/C/Util/7z/makefile.gcc
diff --git a/C/Util/7zipInstall/7zip.ico b/C/Util/7zipInstall/7zip.ico
index 47ffb781..47ffb781 100644..100755
--- a/C/Util/7zipInstall/7zip.ico
+++ b/C/Util/7zipInstall/7zip.ico
Binary files differ
diff --git a/C/Util/7zipInstall/7zipInstall.c b/C/Util/7zipInstall/7zipInstall.c
index 00d0f41a..00d0f41a 100644..100755
--- a/C/Util/7zipInstall/7zipInstall.c
+++ b/C/Util/7zipInstall/7zipInstall.c
diff --git a/C/Util/7zipInstall/7zipInstall.dsp b/C/Util/7zipInstall/7zipInstall.dsp
index d3b5c4c9..d3b5c4c9 100644..100755
--- a/C/Util/7zipInstall/7zipInstall.dsp
+++ b/C/Util/7zipInstall/7zipInstall.dsp
diff --git a/C/Util/7zipInstall/7zipInstall.dsw b/C/Util/7zipInstall/7zipInstall.dsw
index b7db73f4..b7db73f4 100644..100755
--- a/C/Util/7zipInstall/7zipInstall.dsw
+++ b/C/Util/7zipInstall/7zipInstall.dsw
diff --git a/C/Util/7zipInstall/7zipInstall.manifest b/C/Util/7zipInstall/7zipInstall.manifest
index f5c3ae5e..f5c3ae5e 100644..100755
--- a/C/Util/7zipInstall/7zipInstall.manifest
+++ b/C/Util/7zipInstall/7zipInstall.manifest
diff --git a/C/Util/7zipInstall/Precomp.c b/C/Util/7zipInstall/Precomp.c
index 01605e3c..01605e3c 100644..100755
--- a/C/Util/7zipInstall/Precomp.c
+++ b/C/Util/7zipInstall/Precomp.c
diff --git a/C/Util/7zipInstall/Precomp.h b/C/Util/7zipInstall/Precomp.h
index 4c90d479..4c90d479 100644..100755
--- a/C/Util/7zipInstall/Precomp.h
+++ b/C/Util/7zipInstall/Precomp.h
diff --git a/C/Util/7zipInstall/makefile b/C/Util/7zipInstall/makefile
index ab8893a9..ab8893a9 100644..100755
--- a/C/Util/7zipInstall/makefile
+++ b/C/Util/7zipInstall/makefile
diff --git a/C/Util/7zipInstall/resource.h b/C/Util/7zipInstall/resource.h
index 63c6b4c2..63c6b4c2 100644..100755
--- a/C/Util/7zipInstall/resource.h
+++ b/C/Util/7zipInstall/resource.h
diff --git a/C/Util/7zipInstall/resource.rc b/C/Util/7zipInstall/resource.rc
index df6474e3..df6474e3 100644..100755
--- a/C/Util/7zipInstall/resource.rc
+++ b/C/Util/7zipInstall/resource.rc
diff --git a/C/Util/7zipUninstall/7zipUninstall.c b/C/Util/7zipUninstall/7zipUninstall.c
index b4c6ff57..b4c6ff57 100644..100755
--- a/C/Util/7zipUninstall/7zipUninstall.c
+++ b/C/Util/7zipUninstall/7zipUninstall.c
diff --git a/C/Util/7zipUninstall/7zipUninstall.dsp b/C/Util/7zipUninstall/7zipUninstall.dsp
index cc7b6b6b..cc7b6b6b 100644..100755
--- a/C/Util/7zipUninstall/7zipUninstall.dsp
+++ b/C/Util/7zipUninstall/7zipUninstall.dsp
diff --git a/C/Util/7zipUninstall/7zipUninstall.dsw b/C/Util/7zipUninstall/7zipUninstall.dsw
index 2873eda6..2873eda6 100644..100755
--- a/C/Util/7zipUninstall/7zipUninstall.dsw
+++ b/C/Util/7zipUninstall/7zipUninstall.dsw
diff --git a/C/Util/7zipUninstall/7zipUninstall.ico b/C/Util/7zipUninstall/7zipUninstall.ico
index 19eb20ca..19eb20ca 100644..100755
--- a/C/Util/7zipUninstall/7zipUninstall.ico
+++ b/C/Util/7zipUninstall/7zipUninstall.ico
Binary files differ
diff --git a/C/Util/7zipUninstall/7zipUninstall.manifest b/C/Util/7zipUninstall/7zipUninstall.manifest
index a6014434..a6014434 100644..100755
--- a/C/Util/7zipUninstall/7zipUninstall.manifest
+++ b/C/Util/7zipUninstall/7zipUninstall.manifest
diff --git a/C/Util/7zipUninstall/Precomp.c b/C/Util/7zipUninstall/Precomp.c
index 01605e3c..01605e3c 100644..100755
--- a/C/Util/7zipUninstall/Precomp.c
+++ b/C/Util/7zipUninstall/Precomp.c
diff --git a/C/Util/7zipUninstall/Precomp.h b/C/Util/7zipUninstall/Precomp.h
index 4c90d479..4c90d479 100644..100755
--- a/C/Util/7zipUninstall/Precomp.h
+++ b/C/Util/7zipUninstall/Precomp.h
diff --git a/C/Util/7zipUninstall/makefile b/C/Util/7zipUninstall/makefile
index 60c2fe20..60c2fe20 100644..100755
--- a/C/Util/7zipUninstall/makefile
+++ b/C/Util/7zipUninstall/makefile
diff --git a/C/Util/7zipUninstall/resource.h b/C/Util/7zipUninstall/resource.h
index b5c33ff1..b5c33ff1 100644..100755
--- a/C/Util/7zipUninstall/resource.h
+++ b/C/Util/7zipUninstall/resource.h
diff --git a/C/Util/7zipUninstall/resource.rc b/C/Util/7zipUninstall/resource.rc
index 00bdcc07..00bdcc07 100644..100755
--- a/C/Util/7zipUninstall/resource.rc
+++ b/C/Util/7zipUninstall/resource.rc
diff --git a/C/Util/Lzma/LzmaUtil.c b/C/Util/Lzma/LzmaUtil.c
index 62a59079..62a59079 100644..100755
--- a/C/Util/Lzma/LzmaUtil.c
+++ b/C/Util/Lzma/LzmaUtil.c
diff --git a/C/Util/Lzma/LzmaUtil.dsp b/C/Util/Lzma/LzmaUtil.dsp
index 4e38e4a6..4e38e4a6 100644..100755
--- a/C/Util/Lzma/LzmaUtil.dsp
+++ b/C/Util/Lzma/LzmaUtil.dsp
diff --git a/C/Util/Lzma/LzmaUtil.dsw b/C/Util/Lzma/LzmaUtil.dsw
index c52eaf6d..c52eaf6d 100644..100755
--- a/C/Util/Lzma/LzmaUtil.dsw
+++ b/C/Util/Lzma/LzmaUtil.dsw
diff --git a/C/Util/Lzma/makefile b/C/Util/Lzma/makefile
index 7813bdb0..7813bdb0 100644..100755
--- a/C/Util/Lzma/makefile
+++ b/C/Util/Lzma/makefile
diff --git a/C/Util/Lzma/makefile.gcc b/C/Util/Lzma/makefile.gcc
index 2acb0b80..2acb0b80 100644..100755
--- a/C/Util/Lzma/makefile.gcc
+++ b/C/Util/Lzma/makefile.gcc
diff --git a/C/Util/LzmaLib/LzmaLib.def b/C/Util/LzmaLib/LzmaLib.def
index 8bc6add9..8bc6add9 100644..100755
--- a/C/Util/LzmaLib/LzmaLib.def
+++ b/C/Util/LzmaLib/LzmaLib.def
diff --git a/C/Util/LzmaLib/LzmaLib.dsp b/C/Util/LzmaLib/LzmaLib.dsp
index 6ce91dcd..6ce91dcd 100644..100755
--- a/C/Util/LzmaLib/LzmaLib.dsp
+++ b/C/Util/LzmaLib/LzmaLib.dsp
diff --git a/C/Util/LzmaLib/LzmaLib.dsw b/C/Util/LzmaLib/LzmaLib.dsw
index 6faf3336..6faf3336 100644..100755
--- a/C/Util/LzmaLib/LzmaLib.dsw
+++ b/C/Util/LzmaLib/LzmaLib.dsw
diff --git a/C/Util/LzmaLib/LzmaLibExports.c b/C/Util/LzmaLib/LzmaLibExports.c
index 4a28a9a6..4a28a9a6 100644..100755
--- a/C/Util/LzmaLib/LzmaLibExports.c
+++ b/C/Util/LzmaLib/LzmaLibExports.c
diff --git a/C/Util/LzmaLib/makefile b/C/Util/LzmaLib/makefile
index b36f1de0..b36f1de0 100644..100755
--- a/C/Util/LzmaLib/makefile
+++ b/C/Util/LzmaLib/makefile
diff --git a/C/Util/LzmaLib/resource.rc b/C/Util/LzmaLib/resource.rc
index 674832e0..674832e0 100644..100755
--- a/C/Util/LzmaLib/resource.rc
+++ b/C/Util/LzmaLib/resource.rc
diff --git a/C/Util/SfxSetup/Precomp.c b/C/Util/SfxSetup/Precomp.c
index 01605e3c..01605e3c 100644..100755
--- a/C/Util/SfxSetup/Precomp.c
+++ b/C/Util/SfxSetup/Precomp.c
diff --git a/C/Util/SfxSetup/Precomp.h b/C/Util/SfxSetup/Precomp.h
index 588a66f7..588a66f7 100644..100755
--- a/C/Util/SfxSetup/Precomp.h
+++ b/C/Util/SfxSetup/Precomp.h
diff --git a/C/Util/SfxSetup/SfxSetup.c b/C/Util/SfxSetup/SfxSetup.c
index ef19aeac..ef19aeac 100644..100755
--- a/C/Util/SfxSetup/SfxSetup.c
+++ b/C/Util/SfxSetup/SfxSetup.c
diff --git a/C/Util/SfxSetup/SfxSetup.dsp b/C/Util/SfxSetup/SfxSetup.dsp
index 60439a6f..60439a6f 100644..100755
--- a/C/Util/SfxSetup/SfxSetup.dsp
+++ b/C/Util/SfxSetup/SfxSetup.dsp
diff --git a/C/Util/SfxSetup/SfxSetup.dsw b/C/Util/SfxSetup/SfxSetup.dsw
index ea231112..ea231112 100644..100755
--- a/C/Util/SfxSetup/SfxSetup.dsw
+++ b/C/Util/SfxSetup/SfxSetup.dsw
diff --git a/C/Util/SfxSetup/makefile b/C/Util/SfxSetup/makefile
index 544da67d..544da67d 100644..100755
--- a/C/Util/SfxSetup/makefile
+++ b/C/Util/SfxSetup/makefile
diff --git a/C/Util/SfxSetup/makefile_con b/C/Util/SfxSetup/makefile_con
index d0f83525..d0f83525 100644..100755
--- a/C/Util/SfxSetup/makefile_con
+++ b/C/Util/SfxSetup/makefile_con
diff --git a/C/Util/SfxSetup/resource.rc b/C/Util/SfxSetup/resource.rc
index 0c1637f2..0c1637f2 100644..100755
--- a/C/Util/SfxSetup/resource.rc
+++ b/C/Util/SfxSetup/resource.rc
diff --git a/C/Util/SfxSetup/setup.ico b/C/Util/SfxSetup/setup.ico
index dbb6ca8b..dbb6ca8b 100644..100755
--- a/C/Util/SfxSetup/setup.ico
+++ b/C/Util/SfxSetup/setup.ico
Binary files differ
diff --git a/C/Xz.c b/C/Xz.c
index 7c53b600..7c53b600 100644..100755
--- a/C/Xz.c
+++ b/C/Xz.c
diff --git a/C/Xz.h b/C/Xz.h
index 849b944b..849b944b 100644..100755
--- a/C/Xz.h
+++ b/C/Xz.h
diff --git a/C/XzCrc64.c b/C/XzCrc64.c
index b6d02cbe..b6d02cbe 100644..100755
--- a/C/XzCrc64.c
+++ b/C/XzCrc64.c
diff --git a/C/XzCrc64.h b/C/XzCrc64.h
index 08dbc330..08dbc330 100644..100755
--- a/C/XzCrc64.h
+++ b/C/XzCrc64.h
diff --git a/C/XzCrc64Opt.c b/C/XzCrc64Opt.c
index 93a9ffff..93a9ffff 100644..100755
--- a/C/XzCrc64Opt.c
+++ b/C/XzCrc64Opt.c
diff --git a/C/XzDec.c b/C/XzDec.c
index 3f96a37f..3f96a37f 100644..100755
--- a/C/XzDec.c
+++ b/C/XzDec.c
diff --git a/C/XzEnc.c b/C/XzEnc.c
index be174ccc..be174ccc 100644..100755
--- a/C/XzEnc.c
+++ b/C/XzEnc.c
diff --git a/C/XzEnc.h b/C/XzEnc.h
index 0c29e7e1..0c29e7e1 100644..100755
--- a/C/XzEnc.h
+++ b/C/XzEnc.h
diff --git a/C/XzIn.c b/C/XzIn.c
index 84f868ec..84f868ec 100644..100755
--- a/C/XzIn.c
+++ b/C/XzIn.c
diff --git a/C/var_clang.mak b/C/var_clang.mak
index a6df26e7..a6df26e7 100644..100755
--- a/C/var_clang.mak
+++ b/C/var_clang.mak
diff --git a/C/var_clang_arm64.mak b/C/var_clang_arm64.mak
index 4b354096..4b354096 100644..100755
--- a/C/var_clang_arm64.mak
+++ b/C/var_clang_arm64.mak
diff --git a/C/var_clang_x64.mak b/C/var_clang_x64.mak
index 34e1b49c..34e1b49c 100644..100755
--- a/C/var_clang_x64.mak
+++ b/C/var_clang_x64.mak
diff --git a/C/var_clang_x86.mak b/C/var_clang_x86.mak
index bd2317c2..bd2317c2 100644..100755
--- a/C/var_clang_x86.mak
+++ b/C/var_clang_x86.mak
diff --git a/C/var_gcc.mak b/C/var_gcc.mak
index 664491cf..664491cf 100644..100755
--- a/C/var_gcc.mak
+++ b/C/var_gcc.mak
diff --git a/C/var_gcc_arm64.mak b/C/var_gcc_arm64.mak
index 4bbb687d..4bbb687d 100644..100755
--- a/C/var_gcc_arm64.mak
+++ b/C/var_gcc_arm64.mak
diff --git a/C/var_gcc_x64.mak b/C/var_gcc_x64.mak
index 1acf604f..1acf604f 100644..100755
--- a/C/var_gcc_x64.mak
+++ b/C/var_gcc_x64.mak
diff --git a/C/var_gcc_x86.mak b/C/var_gcc_x86.mak
index f0718ec7..f0718ec7 100644..100755
--- a/C/var_gcc_x86.mak
+++ b/C/var_gcc_x86.mak
diff --git a/C/var_mac_arm64.mak b/C/var_mac_arm64.mak
index adf5fa1d..adf5fa1d 100644..100755
--- a/C/var_mac_arm64.mak
+++ b/C/var_mac_arm64.mak
diff --git a/C/var_mac_x64.mak b/C/var_mac_x64.mak
index 13d7aa7f..13d7aa7f 100644..100755
--- a/C/var_mac_x64.mak
+++ b/C/var_mac_x64.mak
diff --git a/C/warn_clang.mak b/C/warn_clang.mak
index ed4f908f..ed4f908f 100644..100755
--- a/C/warn_clang.mak
+++ b/C/warn_clang.mak
diff --git a/C/warn_clang_mac.mak b/C/warn_clang_mac.mak
index 41044a2c..41044a2c 100644..100755
--- a/C/warn_clang_mac.mak
+++ b/C/warn_clang_mac.mak
diff --git a/C/warn_gcc.mak b/C/warn_gcc.mak
index 7aab7a44..7aab7a44 100644..100755
--- a/C/warn_gcc.mak
+++ b/C/warn_gcc.mak
diff --git a/CPP/7zip/7zip.mak b/CPP/7zip/7zip.mak
index 7fbe2ada..7fbe2ada 100644..100755
--- a/CPP/7zip/7zip.mak
+++ b/CPP/7zip/7zip.mak
diff --git a/CPP/7zip/7zip_gcc.mak b/CPP/7zip/7zip_gcc.mak
index e2698a6e..b2424594 100644..100755
--- a/CPP/7zip/7zip_gcc.mak
+++ b/CPP/7zip/7zip_gcc.mak
@@ -382,6 +382,8 @@ $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
@@ -390,6 +392,8 @@ $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
@@ -426,6 +430,8 @@ $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
@@ -448,6 +454,8 @@ $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
diff --git a/CPP/7zip/Aes.mak b/CPP/7zip/Aes.mak
index 7d8da2d8..7d8da2d8 100644..100755
--- a/CPP/7zip/Aes.mak
+++ b/CPP/7zip/Aes.mak
diff --git a/CPP/7zip/Archive/7z/7z.dsp b/CPP/7zip/Archive/7z/7z.dsp
index ffd28721..ffd28721 100644..100755
--- a/CPP/7zip/Archive/7z/7z.dsp
+++ b/CPP/7zip/Archive/7z/7z.dsp
diff --git a/CPP/7zip/Archive/7z/7z.dsw b/CPP/7zip/Archive/7z/7z.dsw
index 702a86c7..702a86c7 100644..100755
--- a/CPP/7zip/Archive/7z/7z.dsw
+++ b/CPP/7zip/Archive/7z/7z.dsw
diff --git a/CPP/7zip/Archive/7z/7zCompressionMode.cpp b/CPP/7zip/Archive/7z/7zCompressionMode.cpp
index 6774fc48..6774fc48 100644..100755
--- a/CPP/7zip/Archive/7z/7zCompressionMode.cpp
+++ b/CPP/7zip/Archive/7z/7zCompressionMode.cpp
diff --git a/CPP/7zip/Archive/7z/7zCompressionMode.h b/CPP/7zip/Archive/7z/7zCompressionMode.h
index 9e846345..9e846345 100644..100755
--- a/CPP/7zip/Archive/7z/7zCompressionMode.h
+++ b/CPP/7zip/Archive/7z/7zCompressionMode.h
diff --git a/CPP/7zip/Archive/7z/7zDecode.cpp b/CPP/7zip/Archive/7z/7zDecode.cpp
index c27c8fbc..c27c8fbc 100644..100755
--- a/CPP/7zip/Archive/7z/7zDecode.cpp
+++ b/CPP/7zip/Archive/7z/7zDecode.cpp
diff --git a/CPP/7zip/Archive/7z/7zDecode.h b/CPP/7zip/Archive/7z/7zDecode.h
index eeb146e3..eeb146e3 100644..100755
--- a/CPP/7zip/Archive/7z/7zDecode.h
+++ b/CPP/7zip/Archive/7z/7zDecode.h
diff --git a/CPP/7zip/Archive/7z/7zEncode.cpp b/CPP/7zip/Archive/7z/7zEncode.cpp
index 83b0f18f..83b0f18f 100644..100755
--- a/CPP/7zip/Archive/7z/7zEncode.cpp
+++ b/CPP/7zip/Archive/7z/7zEncode.cpp
diff --git a/CPP/7zip/Archive/7z/7zEncode.h b/CPP/7zip/Archive/7z/7zEncode.h
index 6ea7f276..6ea7f276 100644..100755
--- a/CPP/7zip/Archive/7z/7zEncode.h
+++ b/CPP/7zip/Archive/7z/7zEncode.h
diff --git a/CPP/7zip/Archive/7z/7zExtract.cpp b/CPP/7zip/Archive/7z/7zExtract.cpp
index 8ca815d4..8ca815d4 100644..100755
--- a/CPP/7zip/Archive/7z/7zExtract.cpp
+++ b/CPP/7zip/Archive/7z/7zExtract.cpp
diff --git a/CPP/7zip/Archive/7z/7zFolderInStream.cpp b/CPP/7zip/Archive/7z/7zFolderInStream.cpp
index a68edf4e..cf50e694 100644..100755
--- a/CPP/7zip/Archive/7z/7zFolderInStream.cpp
+++ b/CPP/7zip/Archive/7z/7zFolderInStream.cpp
@@ -2,6 +2,8 @@
#include "StdAfx.h"
+#include "../../../Windows/TimeUtils.h"
+
#include "7zFolderInStream.h"
namespace NArchive {
@@ -13,17 +15,17 @@ void CFolderInStream::Init(IArchiveUpdateCallback *updateCallback,
_updateCallback = updateCallback;
_indexes = indexes;
_numFiles = numFiles;
- _index = 0;
Processed.ClearAndReserve(numFiles);
CRCs.ClearAndReserve(numFiles);
Sizes.ClearAndReserve(numFiles);
-
- _pos = 0;
- _crc = CRC_INIT_VAL;
- _size_Defined = false;
- _size = 0;
+ if (Need_CTime) CTimes.ClearAndReserve(numFiles);
+ if (Need_ATime) ATimes.ClearAndReserve(numFiles);
+ if (Need_MTime) MTimes.ClearAndReserve(numFiles);
+ if (Need_Attrib) Attribs.ClearAndReserve(numFiles);
+ TimesDefined.ClearAndReserve(numFiles);
+
_stream.Release();
}
@@ -32,44 +34,101 @@ HRESULT CFolderInStream::OpenStream()
_pos = 0;
_crc = CRC_INIT_VAL;
_size_Defined = false;
+ _times_Defined = false;
_size = 0;
+ FILETIME_Clear(_cTime);
+ FILETIME_Clear(_aTime);
+ FILETIME_Clear(_mTime);
+ _attrib = 0;
- while (_index < _numFiles)
+ 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));
+}
+
+/*
+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);
+ const UInt32 crc = CRC_GET_DIGEST(_crc);
+ CRCs.AddInReserved(crc);
+ TimesDefined.AddInReserved(_times_Defined);
+ if (Need_CTime) AddFt(CTimes, _cTime);
+ if (Need_ATime) AddFt(ATimes, _aTime);
+ if (Need_MTime) AddFt(MTimes, _mTime);
+ if (Need_Attrib) Attribs.AddInReserved(_attrib);
+ /*
+ if (isProcessed && _reportArcProp)
+ RINOK(ReportItemProps(_reportArcProp, index, _pos, &crc))
+ */
+ return _updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK);
}
STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
@@ -95,18 +154,10 @@ STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSiz
}
_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());
}
diff --git a/CPP/7zip/Archive/7z/7zFolderInStream.h b/CPP/7zip/Archive/7z/7zFolderInStream.h
index 805db54e..f054e681 100644..100755
--- a/CPP/7zip/Archive/7z/7zFolderInStream.h
+++ b/CPP/7zip/Archive/7z/7zFolderInStream.h
@@ -23,21 +23,37 @@ class CFolderInStream:
UInt64 _pos;
UInt32 _crc;
bool _size_Defined;
+ bool _times_Defined;
UInt64 _size;
+ FILETIME _cTime;
+ FILETIME _aTime;
+ FILETIME _mTime;
+ UInt32 _attrib;
- const UInt32 *_indexes;
unsigned _numFiles;
- unsigned _index;
+ const UInt32 *_indexes;
CMyComPtr<IArchiveUpdateCallback> _updateCallback;
HRESULT OpenStream();
- void AddFileInfo(bool isProcessed);
+ HRESULT AddFileInfo(bool isProcessed);
public:
CRecordVector<bool> Processed;
CRecordVector<UInt32> CRCs;
CRecordVector<UInt64> Sizes;
+ CRecordVector<UInt64> CTimes;
+ CRecordVector<UInt64> ATimes;
+ CRecordVector<UInt64> MTimes;
+ CRecordVector<UInt32> Attribs;
+ CRecordVector<bool> TimesDefined;
+
+ bool Need_CTime;
+ bool Need_ATime;
+ bool Need_MTime;
+ bool Need_Attrib;
+
+ // CMyComPtr<IArchiveUpdateCallbackArcProp> _reportArcProp;
MY_UNKNOWN_IMP2(ISequentialInStream, ICompressGetSubStreamSize)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
@@ -45,7 +61,7 @@ public:
void Init(IArchiveUpdateCallback *updateCallback, const UInt32 *indexes, unsigned numFiles);
- bool WasFinished() const { return _index == _numFiles; }
+ bool WasFinished() const { return Processed.Size() == _numFiles; }
UInt64 GetFullSize() const
{
@@ -54,6 +70,13 @@ public:
size += Sizes[i];
return size;
}
+
+ CFolderInStream():
+ Need_CTime(false),
+ Need_ATime(false),
+ Need_MTime(false),
+ Need_Attrib(false)
+ {}
};
}}
diff --git a/CPP/7zip/Archive/7z/7zHandler.cpp b/CPP/7zip/Archive/7z/7zHandler.cpp
index 9e344c34..ca22f881 100644..100755
--- a/CPP/7zip/Archive/7z/7zHandler.cpp
+++ b/CPP/7zip/Archive/7z/7zHandler.cpp
@@ -278,7 +278,7 @@ static void SetFileTimeProp_From_UInt64Def(PROPVARIANT *prop, const CUInt64DefVe
{
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
diff --git a/CPP/7zip/Archive/7z/7zHandler.h b/CPP/7zip/Archive/7z/7zHandler.h
index cbc2d028..08bd6540 100644..100755
--- a/CPP/7zip/Archive/7z/7zHandler.h
+++ b/CPP/7zip/Archive/7z/7zHandler.h
@@ -49,9 +49,8 @@ public:
bool _encryptHeaders;
// bool _useParents; 9.26
- CBoolPair Write_CTime;
- CBoolPair Write_ATime;
- CBoolPair Write_MTime;
+ CHandlerTimeOptions TimeOptions;
+
CBoolPair Write_Attrib;
bool _useMultiThreadMixer;
diff --git a/CPP/7zip/Archive/7z/7zHandlerOut.cpp b/CPP/7zip/Archive/7z/7zHandlerOut.cpp
index 8f875ce4..bf4e7a69 100644..100755
--- a/CPP/7zip/Archive/7z/7zHandlerOut.cpp
+++ b/CPP/7zip/Archive/7z/7zHandlerOut.cpp
@@ -384,16 +384,16 @@ 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 : true);
+ 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();
}
@@ -719,6 +719,11 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
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.Method = &methodMode;
options.HeaderMethod = (_compressHeaders || encryptHeaders) ? &headerMethod : NULL;
options.UseFilters = (level != 0 && _autoFilter && !methodMode.Filter_was_Inserted);
@@ -817,9 +822,7 @@ void COutHandler::InitProps7z()
_encryptHeaders = false;
// _useParents = false;
- Write_CTime.Init();
- Write_ATime.Init();
- Write_MTime.Init();
+ TimeOptions.Init();
Write_Attrib.Init();
_useMultiThreadMixer = true;
@@ -954,10 +957,20 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val
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);
diff --git a/CPP/7zip/Archive/7z/7zHeader.cpp b/CPP/7zip/Archive/7z/7zHeader.cpp
index acff2fdd..acff2fdd 100644..100755
--- a/CPP/7zip/Archive/7z/7zHeader.cpp
+++ b/CPP/7zip/Archive/7z/7zHeader.cpp
diff --git a/CPP/7zip/Archive/7z/7zHeader.h b/CPP/7zip/Archive/7z/7zHeader.h
index e1bbc0aa..e1bbc0aa 100644..100755
--- a/CPP/7zip/Archive/7z/7zHeader.h
+++ b/CPP/7zip/Archive/7z/7zHeader.h
diff --git a/CPP/7zip/Archive/7z/7zIn.cpp b/CPP/7zip/Archive/7z/7zIn.cpp
index 7134595c..7134595c 100644..100755
--- a/CPP/7zip/Archive/7z/7zIn.cpp
+++ b/CPP/7zip/Archive/7z/7zIn.cpp
diff --git a/CPP/7zip/Archive/7z/7zIn.h b/CPP/7zip/Archive/7z/7zIn.h
index ffa1e4bc..ffa1e4bc 100644..100755
--- a/CPP/7zip/Archive/7z/7zIn.h
+++ b/CPP/7zip/Archive/7z/7zIn.h
diff --git a/CPP/7zip/Archive/7z/7zItem.h b/CPP/7zip/Archive/7z/7zItem.h
index 0f9fdada..0f9fdada 100644..100755
--- a/CPP/7zip/Archive/7z/7zItem.h
+++ b/CPP/7zip/Archive/7z/7zItem.h
diff --git a/CPP/7zip/Archive/7z/7zOut.cpp b/CPP/7zip/Archive/7z/7zOut.cpp
index 2786bf28..2786bf28 100644..100755
--- a/CPP/7zip/Archive/7z/7zOut.cpp
+++ b/CPP/7zip/Archive/7z/7zOut.cpp
diff --git a/CPP/7zip/Archive/7z/7zOut.h b/CPP/7zip/Archive/7z/7zOut.h
index 1ebad56d..1ebad56d 100644..100755
--- a/CPP/7zip/Archive/7z/7zOut.h
+++ b/CPP/7zip/Archive/7z/7zOut.h
diff --git a/CPP/7zip/Archive/7z/7zProperties.cpp b/CPP/7zip/Archive/7z/7zProperties.cpp
index 4cb5a5e6..4cb5a5e6 100644..100755
--- a/CPP/7zip/Archive/7z/7zProperties.cpp
+++ b/CPP/7zip/Archive/7z/7zProperties.cpp
diff --git a/CPP/7zip/Archive/7z/7zProperties.h b/CPP/7zip/Archive/7z/7zProperties.h
index 66181795..66181795 100644..100755
--- a/CPP/7zip/Archive/7z/7zProperties.h
+++ b/CPP/7zip/Archive/7z/7zProperties.h
diff --git a/CPP/7zip/Archive/7z/7zRegister.cpp b/CPP/7zip/Archive/7z/7zRegister.cpp
index 389b5407..eac8b4f2 100644..100755
--- a/CPP/7zip/Archive/7z/7zRegister.cpp
+++ b/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/CPP/7zip/Archive/7z/7zSpecStream.cpp b/CPP/7zip/Archive/7z/7zSpecStream.cpp
index 8e45d987..8e45d987 100644..100755
--- a/CPP/7zip/Archive/7z/7zSpecStream.cpp
+++ b/CPP/7zip/Archive/7z/7zSpecStream.cpp
diff --git a/CPP/7zip/Archive/7z/7zSpecStream.h b/CPP/7zip/Archive/7z/7zSpecStream.h
index 21155069..21155069 100644..100755
--- a/CPP/7zip/Archive/7z/7zSpecStream.h
+++ b/CPP/7zip/Archive/7z/7zSpecStream.h
diff --git a/CPP/7zip/Archive/7z/7zUpdate.cpp b/CPP/7zip/Archive/7z/7zUpdate.cpp
index b641d93f..b6fd1924 100644..100755
--- a/CPP/7zip/Archive/7z/7zUpdate.cpp
+++ b/CPP/7zip/Archive/7z/7zUpdate.cpp
@@ -804,10 +804,20 @@ struct CAnalysis
bool ParseExe;
bool ParseAll;
+ /*
+ bool Need_ATime;
+ bool ATime_Defined;
+ FILETIME ATime;
+ */
+
CAnalysis():
ParseWav(true),
ParseExe(false),
ParseAll(false)
+ /*
+ , Need_ATime(false)
+ , ATime_Defined(false)
+ */
{}
HRESULT GetFilterGroup(UInt32 index, const CUpdateItem &ui, CFilterMode &filterMode);
@@ -887,6 +897,18 @@ HRESULT CAnalysis::GetFilterGroup(UInt32 index, const CUpdateItem &ui, CFilterMo
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();
@@ -1586,6 +1608,11 @@ HRESULT Update(
CMyComPtr<IArchiveExtractCallbackMessage> extractCallback;
updateCallback->QueryInterface(IID_IArchiveExtractCallbackMessage, (void **)&extractCallback);
+ /*
+ CMyComPtr<IArchiveUpdateCallbackArcProp> reportArcProp;
+ updateCallback->QueryInterface(IID_IArchiveUpdateCallbackArcProp, (void **)&reportArcProp);
+ */
+
// size_t totalSecureDataSize = (size_t)secureBlocks.GetTotalSizeInBytes();
/*
@@ -1756,6 +1783,7 @@ HRESULT Update(
{
CAnalysis analysis;
+ // analysis.Need_ATime = options.Need_ATime;
if (options.AnalysisLevel == 0)
{
analysis.ParseWav = false;
@@ -1790,7 +1818,15 @@ HRESULT Update(
CFilterMode2 fm;
if (useFilters)
{
+ // 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;
@@ -2374,13 +2410,33 @@ HRESULT Update(
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->Init(updateCallback, &indices[i], numSubFiles);
unsigned startPackIndex = newDatabase.PackSizes.Size();
UInt64 curFolderUnpackSize = totalSize;
- // curFolderUnpackSize = (UInt64)(Int64)-1;
+ // curFolderUnpackSize = (UInt64)(Int64)-1; // for debug
RINOK(encoder.Encode(
EXTERNAL_CODECS_LOC_VARS
@@ -2393,8 +2449,11 @@ HRESULT Update(
if (!inStreamSpec->WasFinished())
return E_FAIL;
+ 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 ()
@@ -2403,7 +2462,9 @@ HRESULT Update(
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]];
@@ -2429,14 +2490,16 @@ HRESULT Update(
*/
if (!inStreamSpec->Processed[subIndex])
{
+ // we don't add file here
skippedSize += ui.Size;
- continue;
- // file.Name += ".locked";
+ continue; // comment it for debug
+ // name += ".locked"; // for debug
}
file.Crc = inStreamSpec->CRCs[subIndex];
file.Size = inStreamSpec->Sizes[subIndex];
+ procSize += file.Size;
// if (file.Size >= 0) // test purposes
if (file.Size != 0)
{
@@ -2450,6 +2513,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)
@@ -2457,9 +2537,22 @@ 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);
}
+ // it's optional check to ensure that sizes are correct
+ if (procSize != curFolderUnpackSize)
+ return E_FAIL;
+
// numUnpackStreams = 0 is very bad case for locked files
// v3.13 doesn't understand it.
newDatabase.NumUnpackStreamsVector.Add(numUnpackStreams);
@@ -2470,6 +2563,44 @@ HRESULT Update(
complexity -= skippedSize;
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));
+ }
+ */
}
}
diff --git a/CPP/7zip/Archive/7z/7zUpdate.h b/CPP/7zip/Archive/7z/7zUpdate.h
index 7c0f78a8..e6c48cae 100644..100755
--- a/CPP/7zip/Archive/7z/7zUpdate.h
+++ b/CPP/7zip/Archive/7z/7zUpdate.h
@@ -62,6 +62,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 +78,7 @@ struct CUpdateItem
CTimeDefined(false),
ATimeDefined(false),
MTimeDefined(false)
+ // , ATime_WasReadByAnalysis(false)
// SecureIndex(0)
{}
void SetDirStatusFromAttrib() { IsDir = ((Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0); }
@@ -103,6 +106,11 @@ struct CUpdateOptions
bool RemoveSfxBlock;
bool MultiThreadMixer;
+ bool Need_CTime;
+ bool Need_ATime;
+ bool Need_MTime;
+ bool Need_Attrib;
+
CUpdateOptions():
Method(NULL),
HeaderMethod(NULL),
@@ -114,7 +122,11 @@ struct CUpdateOptions
SolidExtension(false),
UseTypeSorting(true),
RemoveSfxBlock(false),
- MultiThreadMixer(true)
+ MultiThreadMixer(true),
+ Need_CTime(false),
+ Need_ATime(false),
+ Need_MTime(false),
+ Need_Attrib(false)
{}
};
diff --git a/CPP/7zip/Archive/7z/StdAfx.cpp b/CPP/7zip/Archive/7z/StdAfx.cpp
index d0feea85..d0feea85 100644..100755
--- a/CPP/7zip/Archive/7z/StdAfx.cpp
+++ b/CPP/7zip/Archive/7z/StdAfx.cpp
diff --git a/CPP/7zip/Archive/7z/StdAfx.h b/CPP/7zip/Archive/7z/StdAfx.h
index 2854ff3e..2854ff3e 100644..100755
--- a/CPP/7zip/Archive/7z/StdAfx.h
+++ b/CPP/7zip/Archive/7z/StdAfx.h
diff --git a/CPP/7zip/Archive/7z/makefile b/CPP/7zip/Archive/7z/makefile
index a3b077da..a3b077da 100644..100755
--- a/CPP/7zip/Archive/7z/makefile
+++ b/CPP/7zip/Archive/7z/makefile
diff --git a/CPP/7zip/Archive/7z/resource.rc b/CPP/7zip/Archive/7z/resource.rc
index f79dac08..f79dac08 100644..100755
--- a/CPP/7zip/Archive/7z/resource.rc
+++ b/CPP/7zip/Archive/7z/resource.rc
diff --git a/CPP/7zip/Archive/ApfsHandler.cpp b/CPP/7zip/Archive/ApfsHandler.cpp
new file mode 100755
index 00000000..8312456b
--- /dev/null
+++ b/CPP/7zip/Archive/ApfsHandler.cpp
@@ -0,0 +1,3546 @@
+// ApfsHandler.cpp
+
+#include "StdAfx.h"
+
+// #define SHOW_DEBUG_INFO
+
+#ifdef SHOW_DEBUG_INFO
+#include <stdio.h>
+#define PRF(x) x
+#else
+#define PRF(x)
+#endif
+
+#include "../../../C/CpuArch.h"
+
+#include "../../Common/ComTry.h"
+#include "../../Common/IntToString.h"
+#include "../../Common/MyLinux.h"
+#include "../../Common/UTFConvert.h"
+
+#include "../../Windows/PropVariantConv.h"
+#include "../../Windows/PropVariantUtils.h"
+#include "../../Windows/TimeUtils.h"
+
+#include "../Common/LimitedStreams.h"
+#include "../Common/ProgressUtils.h"
+#include "../Common/RegisterArc.h"
+#include "../Common/StreamObjects.h"
+#include "../Common/StreamUtils.h"
+
+#include "../Compress/CopyCoder.h"
+
+#include "Common/ItemNameUtils.h"
+
+// if APFS_SHOW_ALT_STREAMS is defined, the handler will show attribute files.
+#define APFS_SHOW_ALT_STREAMS
+
+#define VI_MINUS1 ((unsigned)(int)-1)
+#define IsViDef(x) ((int)(x) != -1)
+#define IsViNotDef(x) ((int)(x) == -1)
+
+#define Get16(p) GetUi16(p)
+#define Get32(p) GetUi32(p)
+#define Get64(p) GetUi64(p)
+
+#define G16(_offs_, dest) dest = Get16(p + (_offs_));
+#define G32(_offs_, dest) dest = Get32(p + (_offs_));
+#define G64(_offs_, dest) dest = Get64(p + (_offs_));
+
+namespace NArchive {
+namespace NApfs {
+
+#define ValToHex(t) ((char)(((t) < 10) ? ('0' + (t)) : ('a' + ((t) - 10))))
+
+static void ConvertByteToHex(unsigned val, char *s)
+{
+ unsigned t;
+ t = val >> 4;
+ s[0] = ValToHex(t);
+ t = val & 0xF;
+ s[1] = ValToHex(t);
+}
+
+struct CUuid
+{
+ Byte Data[16];
+
+ void SetHex_To_str(char *s) const
+ {
+ for (unsigned i = 0; i < 16; i++)
+ ConvertByteToHex(Data[i], s + i * 2);
+ s[32] = 0;
+ }
+
+ void AddHexToString(UString &dest) const
+ {
+ char temp[32 + 4];
+ SetHex_To_str(temp);
+ dest += temp;
+ }
+
+ void SetFrom(const Byte *p) { memcpy(Data, p, 16); }
+};
+
+
+typedef UInt64 oid_t;
+typedef UInt64 xid_t;
+typedef Int64 paddr_t;
+
+#define G64o G64
+#define G64x G64
+// #define G64a G64
+
+/*
+struct prange_t
+{
+ paddr_t start_paddr;
+ UInt64 block_count;
+
+ void Parse(const Byte *p)
+ {
+ G64a (0, start_paddr);
+ G64 (8, block_count);
+ }
+};
+*/
+
+#define OBJECT_TYPE_NX_SUPERBLOCK 0x1
+#define OBJECT_TYPE_BTREE 0x2
+#define OBJECT_TYPE_BTREE_NODE 0x3
+/*
+#define OBJECT_TYPE_SPACEMAN 0x5
+#define OBJECT_TYPE_SPACEMAN_CAB 0x6
+#define OBJECT_TYPE_SPACEMAN_CIB 0x7
+#define OBJECT_TYPE_SPACEMAN_BITMAP 0x8
+#define OBJECT_TYPE_SPACEMAN_FREE_QUEUE 0x9
+#define OBJECT_TYPE_EXTENT_LIST_TREE 0xa
+*/
+#define OBJECT_TYPE_OMAP 0xb
+/*
+#define OBJECT_TYPE_CHECKPOINT_MAP 0xc
+*/
+#define OBJECT_TYPE_FS 0xd
+#define OBJECT_TYPE_FSTREE 0xe
+/*
+#define OBJECT_TYPE_BLOCKREFTREE 0xf
+#define OBJECT_TYPE_SNAPMETATREE 0x10
+#define OBJECT_TYPE_NX_REAPER 0x11
+#define OBJECT_TYPE_NX_REAP_LIST 0x12
+#define OBJECT_TYPE_OMAP_SNAPSHOT 0x13
+#define OBJECT_TYPE_EFI_JUMPSTART 0x14
+#define OBJECT_TYPE_FUSION_MIDDLE_TREE 0x15
+#define OBJECT_TYPE_NX_FUSION_WBC 0x16
+#define OBJECT_TYPE_NX_FUSION_WBC_LIST 0x17
+#define OBJECT_TYPE_ER_STATE 0x18
+#define OBJECT_TYPE_GBITMAP 0x19
+#define OBJECT_TYPE_GBITMAP_TREE 0x1a
+#define OBJECT_TYPE_GBITMAP_BLOCK 0x1b
+#define OBJECT_TYPE_ER_RECOVERY_BLOCK 0x1c
+#define OBJECT_TYPE_SNAP_META_EXT 0x1d
+#define OBJECT_TYPE_INTEGRITY_META 0x1e
+#define OBJECT_TYPE_FEXT_TREE 0x1f
+#define OBJECT_TYPE_RESERVED_20 0x20
+
+#define OBJECT_TYPE_INVALID 0x0
+#define OBJECT_TYPE_TEST 0xff
+#define OBJECT_TYPE_CONTAINER_KEYBAG 'keys'
+#define OBJECT_TYPE_VOLUME_KEYBAG 'recs'
+#define OBJECT_TYPE_MEDIA_KEYBAG 'mkey'
+
+#define OBJ_VIRTUAL 0x0
+#define OBJ_EPHEMERAL 0x80000000
+#define OBJ_PHYSICAL 0x40000000
+
+#define OBJ_NOHEADER 0x20000000
+#define OBJ_ENCRYPTED 0x10000000
+#define OBJ_NONPERSISTENT 0x08000000
+*/
+#define OBJECT_TYPE_MASK 0x0000ffff
+/*
+#define OBJECT_TYPE_FLAGS_MASK 0xffff0000
+#define OBJ_STORAGETYPE_MASK 0xc0000000
+#define OBJECT_TYPE_FLAGS_DEFINED_MASK 0xf8000000
+*/
+
+// #define MAX_CKSUM_SIZE 8
+
+// obj_phys_t
+struct CPhys
+{
+ // Byte cksum[MAX_CKSUM_SIZE];
+ oid_t oid;
+ xid_t xid;
+ UInt32 type;
+ UInt32 subtype;
+
+ UInt32 GetType() const { return type & OBJECT_TYPE_MASK; }
+ void Parse(const Byte *p);
+};
+
+void CPhys::Parse(const Byte *p)
+{
+ // memcpy(cksum, p, MAX_CKSUM_SIZE);
+ G64o (8, oid);
+ G64x (0x10, xid);
+ G32 (0x18, type);
+ G32 (0x1C, subtype);
+}
+
+#define NX_MAX_FILE_SYSTEMS 100
+/*
+#define NX_EPH_INFO_COUNT 4
+#define NX_EPH_MIN_BLOCK_COUNT 8
+#define NX_MAX_FILE_SYSTEM_EPH_STRUCTS 4
+#define NX_TX_MIN_CHECKPOINT_COUNT 4
+#define NX_EPH_INFO_VERSION_1 1
+*/
+
+/*
+typedef enum
+{
+ NX_CNTR_OBJ_CKSUM_SET = 0,
+ NX_CNTR_OBJ_CKSUM_FAIL = 1,
+ NX_NUM_COUNTERS = 32
+} counter_id_t;
+*/
+
+/* Incompatible volume feature flags */
+#define APFS_INCOMPAT_CASE_INSENSITIVE (1 << 0)
+/*
+#define APFS_INCOMPAT_DATALESS_SNAPS (1 << 1)
+#define APFS_INCOMPAT_ENC_ROLLED (1 << 2)
+*/
+#define APFS_INCOMPAT_NORMALIZATION_INSENSITIVE (1 << 3)
+/*
+#define APFS_INCOMPAT_INCOMPLETE_RESTORE (1 << 4)
+#define APFS_INCOMPAT_SEALED_VOLUME (1 << 5)
+#define APFS_INCOMPAT_RESERVED_40 (1 << 6)
+*/
+
+static const char * const g_APFS_INCOMPAT_Flags[] =
+{
+ "CASE_INSENSITIVE"
+ , "DATALESS_SNAPS"
+ , "ENC_ROLLED"
+ , "NORMALIZATION_INSENSITIVE"
+ , "INCOMPLETE_RESTORE"
+ , "SEALED_VOLUME"
+};
+
+/*
+#define APFS_SUPPORTED_INCOMPAT_MASK \
+ ( APFS_INCOMPAT_CASE_INSENSITIVE \
+ | APFS_INCOMPAT_DATALESS_SNAPS \
+ | APFS_INCOMPAT_ENC_ROLLED \
+ | APFS_INCOMPAT_NORMALIZATION_INSENSITIVE \
+ | APFS_INCOMPAT_INCOMPLETE_RESTORE \
+ | APFS_INCOMPAT_SEALED_VOLUME \
+ | APFS_INCOMPAT_RESERVED_40 \
+)
+*/
+
+// superblock_t
+struct CSuperBlock
+{
+ // CPhys o;
+ // UInt32 magic;
+ UInt32 block_size;
+ unsigned block_size_Log;
+ UInt64 block_count;
+ // UInt64 features;
+ // UInt64 readonly_compatible_features;
+ // UInt64 incompatible_features;
+ CUuid uuid;
+ /*
+ oid_t next_oid;
+ xid_t next_xid;
+ UInt32 xp_desc_blocks;
+ UInt32 xp_data_blocks;
+ paddr_t xp_desc_base;
+ paddr_t xp_data_base;
+ UInt32 xp_desc_next;
+ UInt32 xp_data_next;
+ UInt32 xp_desc_index;
+ UInt32 xp_desc_len;
+ UInt32 xp_data_index;
+ UInt32 xp_data_len;
+ oid_t spaceman_oid;
+ */
+ oid_t omap_oid;
+ // oid_t reaper_oid;
+ // UInt32 test_type;
+ UInt32 max_file_systems;
+ // oid_t fs_oid[NX_MAX_FILE_SYSTEMS];
+ /*
+ UInt64 counters[NX_NUM_COUNTERS]; // counter_id_t
+ prange_t blocked_out_prange;
+ oid_t evict_mapping_tree_oid;
+ UInt64 flags;
+ paddr_t efi_jumpstart;
+ CUuid fusion_uuid;
+ prange_t keylocker;
+ UInt64 ephemeral_info[NX_EPH_INFO_COUNT];
+ oid_t test_oid;
+ oid_t fusion_mt_oid;
+ oid_t fusion_wbc_oid;
+ prange_t fusion_wbc;
+ UInt64 newest_mounted_version;
+ prange_t mkb_locker;
+ */
+
+ bool Parse(const Byte *p);
+};
+
+struct CSuperBlock2
+{
+ oid_t fs_oid[NX_MAX_FILE_SYSTEMS];
+ void Parse(const Byte *p)
+ {
+ for (unsigned i = 0; i < NX_MAX_FILE_SYSTEMS; i++)
+ {
+ G64o (0xb8 + i * 8, fs_oid[i]);
+ }
+ }
+};
+
+
+// we include one additional byte of next field (block_size)
+static const unsigned k_SignatureOffset = 32;
+static const Byte k_Signature[] = { 'N', 'X', 'S', 'B', 0 };
+
+// size must be 4 bytes aligned
+static UInt64 Fletcher64(const Byte *data, size_t size)
+{
+ const UInt32 kMax32 = 0xffffffff;
+ const UInt64 val = 0; // startVal
+ UInt64 a = val & kMax32;
+ UInt64 b = (val >> 32) & kMax32;
+ for (size_t i = 0; i < size; i += 4)
+ {
+ a += GetUi32(data + i);
+ b += a;
+ }
+ a %= kMax32;
+ b %= kMax32;
+ b = (UInt32)(kMax32 - ((a + b) % kMax32));
+ a = (UInt32)(kMax32 - ((a + b) % kMax32));
+ return (a << 32) | b;
+}
+
+static bool CheckFletcher64(const Byte *p, size_t size)
+{
+ const UInt64 calculated_checksum = Fletcher64(p + 8, size - 8);
+ const UInt64 stored_checksum = Get64(p);
+ return (stored_checksum == calculated_checksum);
+}
+
+
+static unsigned GetLogSize(UInt32 size)
+{
+ unsigned k;
+ for (k = 0; k < 32; k++)
+ if (((UInt32)1 << k) == size)
+ return k;
+ return k;
+}
+
+static const unsigned kApfsHeaderSize = 1 << 12;
+
+// #define OID_INVALID 0
+#define OID_NX_SUPERBLOCK 1
+// #define OID_RESERVED_COUNT 1024
+// This range of identifiers is reserved for physical, virtual, and ephemeral objects
+
+bool CSuperBlock::Parse(const Byte *p)
+{
+ CPhys o;
+ o.Parse(p);
+ if (o.oid != OID_NX_SUPERBLOCK)
+ return false;
+ if (o.GetType() != OBJECT_TYPE_NX_SUPERBLOCK)
+ return false;
+ if (o.subtype != 0)
+ return false;
+ if (memcmp(p + k_SignatureOffset, k_Signature, 4) != 0)
+ return false;
+ if (!CheckFletcher64(p, kApfsHeaderSize))
+ return false;
+
+ G32 (0x24, block_size);
+ {
+ unsigned logSize = GetLogSize(block_size);
+ if (logSize < 12 || logSize > 16)
+ return false;
+ block_size_Log = logSize;
+ }
+
+ G64 (0x28, block_count);
+
+ static const UInt64 kArcSize_MAX = (UInt64)1 << 62;
+ if (block_count > (kArcSize_MAX >> block_size_Log))
+ return false;
+
+ // G64 (0x30, features);
+ // G64 (0x38, readonly_compatible_features);
+ // G64 (0x40, incompatible_features);
+ uuid.SetFrom(p + 0x48);
+ /*
+ G64o (0x58, next_oid);
+ G64x (0x60, next_xid);
+ G32 (0x68, xp_desc_blocks);
+ G32 (0x6c, xp_data_blocks);
+ G64a (0x70, xp_desc_base);
+ G64a (0x78, xp_data_base);
+ G32 (0x80, xp_desc_next);
+ G32 (0x84, xp_data_next);
+ G32 (0x88, xp_desc_index);
+ G32 (0x8c, xp_desc_len);
+ G32 (0x90, xp_data_index);
+ G32 (0x94, xp_data_len);
+ G64o (0x98, spaceman_oid);
+ */
+ G64o (0xa0, omap_oid);
+ // G64o (0xa8, reaper_oid);
+ // G32 (0xb0, test_type);
+ G32 (0xb4, max_file_systems);
+ if (max_file_systems > NX_MAX_FILE_SYSTEMS)
+ return false;
+ /*
+ {
+ for (unsigned i = 0; i < NX_MAX_FILE_SYSTEMS; i++)
+ {
+ G64o (0xb8 + i * 8, fs_oid[i]);
+ }
+ }
+ */
+ /*
+ {
+ for (unsigned i = 0; i < NX_NUM_COUNTERS; i++)
+ {
+ G64 (0x3d8 + i * 8, counters[i]);
+ }
+ }
+ blocked_out_prange.Parse(p + 0x4d8);
+ G64o (0x4e8, evict_mapping_tree_oid);
+ #define NX_CRYPTO_SW 0x00000004LL
+ G64 (0x4f0, flags);
+ G64a (0x4f8, efi_jumpstart);
+ fusion_uuid.SetFrom(p + 0x500);
+ keylocker.Parse(p + 0x510);
+ {
+ for (unsigned i = 0; i < NX_EPH_INFO_COUNT; i++)
+ {
+ G64 (0x520 + i * 8, ephemeral_info[i]);
+ }
+ }
+ G64o (0x540, test_oid);
+ G64o (0x548, fusion_mt_oid);
+ G64o (0x550, fusion_wbc_oid);
+ fusion_wbc.Parse(p + 0x558);
+ G64 (0x568, newest_mounted_version); // decimal 1412141 001 000 000
+ mkb_locker.Parse(p + 0x570);
+ */
+
+ return true;
+}
+
+
+
+struct C_omap_phys
+{
+ // om_ prefix
+ // CPhys o;
+ /*
+ UInt32 flags;
+ UInt32 snap_count;
+ UInt32 tree_type;
+ UInt32 snapshot_tree_type;
+ */
+ oid_t tree_oid;
+ /*
+ oid_t snapshot_tree_oid;
+ xid_t most_recent_snap;
+ xid_t pending_revert_min;
+ xid_t pending_revert_max;
+ */
+ bool Parse(const Byte *p, size_t size, oid_t oid);
+};
+
+bool C_omap_phys::Parse(const Byte *p, size_t size, oid_t oid)
+{
+ CPhys o;
+ if (!CheckFletcher64(p, size))
+ return false;
+ o.Parse(p);
+ if (o.GetType() != OBJECT_TYPE_OMAP)
+ return false;
+ if (o.oid != oid)
+ return false;
+ /*
+ G32 (0x20, flags);
+ G32 (0x24, snap_count);
+ G32 (0x28, tree_type);
+ G32 (0x2C, snapshot_tree_type);
+ */
+ G64o (0x30, tree_oid);
+ /*
+ G64o (0x38, snapshot_tree_oid);
+ G64x (0x40, most_recent_snap);
+ G64x (0x48, pending_revert_min);
+ G64x (0x50, pending_revert_max);
+ */
+ return true;
+}
+
+
+// #define BTOFF_INVALID 0xffff
+/* This value is stored in the off field of nloc_t to indicate that
+there's no offset. For example, the last entry in a free
+list has no entry after it, so it uses this value for its off field. */
+
+// A location within a B-tree node
+struct nloc
+{
+ UInt16 off;
+ UInt16 len;
+
+ void Parse(const Byte *p)
+ {
+ G16 (0, off);
+ G16 (2, len);
+ }
+ UInt32 GetEnd() const { return (UInt32)off + len; }
+ bool CheckOverLimit(UInt32 limit)
+ {
+ return off < limit && len <= limit - off;
+ }
+};
+
+
+// The location, within a B-tree node, of a key and value
+struct kvloc
+{
+ nloc k;
+ nloc v;
+
+ void Parse(const Byte *p)
+ {
+ k.Parse(p);
+ v.Parse(p + 4);
+ }
+};
+
+
+// The location, within a B-tree node, of a fixed-size key and value
+struct kvoff
+{
+ UInt16 k;
+ UInt16 v;
+
+ void Parse(const Byte *p)
+ {
+ G16 (0, k);
+ G16 (2, v);
+ }
+};
+
+
+#define BTNODE_ROOT (1 << 0)
+#define BTNODE_LEAF (1 << 1)
+#define BTNODE_FIXED_KV_SIZE (1 << 2)
+/*
+#define BTNODE_HASHED (1 << 3)
+#define BTNODE_NOHEADER (1 << 4)
+#define BTNODE_CHECK_KOFF_INVAL (1 << 15)
+*/
+
+static const unsigned k_Toc_offset = 0x38;
+
+// btree_node_phys
+struct CBTreeNodePhys
+{
+ // btn_ prefix
+ CPhys o;
+ UInt16 flags;
+ UInt16 level; // the number of child levels below this node. 0 - for a leaf node, 1 for the immediate parent of a leaf node
+ UInt32 nkeys; // The number of keys stored in this node.
+ nloc table_space;
+ /*
+ nloc free_space;
+ nloc key_free_list;
+ nloc val_free_list;
+ */
+
+ bool Is_FIXED_KV_SIZE() const { return (flags & BTNODE_FIXED_KV_SIZE) != 0; }
+
+ bool Parse(const Byte *p, size_t size)
+ {
+ if (!CheckFletcher64(p, size))
+ return false;
+ o.Parse(p);
+ G16 (0x20, flags);
+ G16 (0x22, level);
+ G32 (0x24, nkeys);
+ table_space.Parse(p + 0x28);
+ /*
+ free_space.Parse(p + 0x2C);
+ key_free_list.Parse(p + 0x30);
+ val_free_list.Parse(p + 0x34);
+ */
+ return true;
+ }
+};
+
+/*
+#define BTREE_UINT64_KEYS (1 << 0)
+#define BTREE_SEQUENTIAL_INSERT (1 << 1)
+#define BTREE_ALLOW_GHOSTS (1 << 2)
+*/
+#define BTREE_EPHEMERAL (1 << 3)
+#define BTREE_PHYSICAL (1 << 4)
+/*
+#define BTREE_NONPERSISTENT (1 << 5)
+#define BTREE_KV_NONALIGNED (1 << 6)
+#define BTREE_HASHED (1 << 7)
+*/
+
+/*
+ BTREE_EPHEMERAL: The nodes in the B-tree use ephemeral object identifiers to link to child nodes
+ BTREE_PHYSICAL : The nodes in the B-tree use physical object identifiers to link to child nodes.
+ If neither flag is set, nodes in the B-tree use virtual object
+ identifiers to link to their child nodes.
+*/
+
+// Static information about a B-tree.
+struct btree_info_fixed
+{
+ UInt32 flags;
+ UInt32 node_size;
+ UInt32 key_size;
+ UInt32 val_size;
+
+ void Parse(const Byte *p)
+ {
+ G32 (0, flags);
+ G32 (4, node_size);
+ G32 (8, key_size);
+ G32 (12, val_size);
+ }
+};
+
+static const unsigned k_btree_info_Size = 0x28;
+
+struct btree_info
+{
+ btree_info_fixed fixed;
+ UInt32 longest_key;
+ UInt32 longest_val;
+ UInt64 key_count;
+ UInt64 node_count;
+
+ bool Is_EPHEMERAL() const { return (fixed.flags & BTREE_EPHEMERAL) != 0; }
+ bool Is_PHYSICAL() const { return (fixed.flags & BTREE_PHYSICAL) != 0; }
+
+ void Parse(const Byte *p)
+ {
+ fixed.Parse(p);
+ G32 (0x10, longest_key);
+ G32 (0x14, longest_val);
+ G64 (0x18, key_count);
+ G64 (0x20, node_count);
+ }
+};
+
+
+/*
+typedef UInt32 cp_key_class_t;
+typedef UInt32 cp_key_os_version_t;
+typedef UInt16 cp_key_revision_t;
+typedef UInt32 crypto_flags_t;
+
+struct wrapped_meta_crypto_state
+{
+ UInt16 major_version;
+ UInt16 minor_version;
+ crypto_flags_t cpflags;
+ cp_key_class_t persistent_class;
+ cp_key_os_version_t key_os_version;
+ cp_key_revision_t key_revision;
+ // UInt16 unused;
+
+ void Parse(const Byte *p)
+ {
+ G16 (0, major_version);
+ G16 (2, minor_version);
+ G32 (4, cpflags);
+ G32 (8, persistent_class);
+ G32 (12, key_os_version);
+ G16 (16, key_revision);
+ }
+};
+*/
+
+
+#define APFS_MODIFIED_NAMELEN 32
+#define sizeof__apfs_modified_by_t (APFS_MODIFIED_NAMELEN + 16);
+
+struct apfs_modified_by_t
+{
+ Byte id[APFS_MODIFIED_NAMELEN];
+ UInt64 timestamp;
+ xid_t last_xid;
+
+ void Parse(const Byte *p)
+ {
+ memcpy(id, p, APFS_MODIFIED_NAMELEN);
+ p += APFS_MODIFIED_NAMELEN;
+ G64 (0, timestamp);
+ G64x (8, last_xid);
+ }
+};
+
+
+#define APFS_MAX_HIST 8
+#define APFS_VOLNAME_LEN 256
+
+struct CApfs
+{
+ // apfs_
+ CPhys o;
+ // UInt32 magic;
+ UInt32 fs_index; // e index of the object identifier for this volume's file system in the container's array of file systems.
+ // UInt64 features;
+ // UInt64 readonly_compatible_features;
+ UInt64 incompatible_features;
+ UInt64 unmount_time;
+ // UInt64 fs_reserve_block_count;
+ // UInt64 fs_quota_block_count;
+ UInt64 fs_alloc_count;
+ // wrapped_meta_crypto_state meta_crypto;
+ // UInt32 root_tree_type;
+ /* The type of the root file-system tree.
+ The value is typically OBJ_VIRTUAL | OBJECT_TYPE_BTREE,
+ with a subtype of OBJECT_TYPE_FSTREE */
+
+ // UInt32 extentref_tree_type;
+ // UInt32 snap_meta_tree_type;
+ oid_t omap_oid;
+ oid_t root_tree_oid;
+ /*
+ oid_t extentref_tree_oid;
+ oid_t snap_meta_tree_oid;
+ xid_t revert_to_xid;
+ oid_t revert_to_sblock_oid;
+ UInt64 next_obj_id;
+ */
+ UInt64 num_files;
+ UInt64 num_directories;
+ UInt64 num_symlinks;
+ UInt64 num_other_fsobjects;
+ UInt64 num_snapshots;
+ UInt64 total_blocks_alloced;
+ UInt64 total_blocks_freed;
+ CUuid vol_uuid;
+ UInt64 last_mod_time;
+ UInt64 fs_flags;
+ apfs_modified_by_t formatted_by;
+ apfs_modified_by_t modified_by[APFS_MAX_HIST];
+ Byte volname[APFS_VOLNAME_LEN];
+ /*
+ UInt32 next_doc_id;
+ UInt16 role; // APFS_VOL_ROLE_NONE APFS_VOL_ROLE_SYSTEM ....
+ UInt16 reserved;
+ xid_t root_to_xid;
+ oid_t er_state_oid;
+ UInt64 cloneinfo_id_epoch;
+ UInt64 cloneinfo_xid;
+ oid_t snap_meta_ext_oid;
+ CUuid volume_group_id;
+ oid_t integrity_meta_oid;
+ oid_t fext_tree_oid;
+ UInt32 fext_tree_type;
+ UInt32 reserved_type;
+ oid_t reserved_oid;
+ */
+
+ UInt64 GetTotalItems() const
+ {
+ return num_files + num_directories + num_symlinks + num_other_fsobjects;
+ }
+
+ bool IsHashedName() const
+ {
+ return
+ (incompatible_features & APFS_INCOMPAT_CASE_INSENSITIVE) != 0 ||
+ (incompatible_features & APFS_INCOMPAT_NORMALIZATION_INSENSITIVE) != 0;
+ }
+
+ bool Parse(const Byte *p, size_t size);
+};
+
+
+bool CApfs::Parse(const Byte *p, size_t size)
+{
+ o.Parse(p);
+ if (Get32(p + 32) != 0x42535041) // { 'A', 'P', 'S', 'B' };
+ return false;
+ if (o.GetType() != OBJECT_TYPE_FS)
+ return false;
+ if (!CheckFletcher64(p, size))
+ return false;
+ // if (o.GetType() != OBJECT_TYPE_NX_SUPERBLOCK) return false;
+
+ G32 (0x24, fs_index);
+ // G64 (0x28, features);
+ // G64 (0x30, readonly_compatible_features);
+ G64 (0x38, incompatible_features);
+ G64 (0x40, unmount_time);
+ // G64 (0x48, fs_reserve_block_count);
+ // G64 (0x50, fs_quota_block_count);
+ G64 (0x58, fs_alloc_count);
+ // meta_crypto.Parse(p + 0x60);
+ // G32 (0x74, root_tree_type);
+ // G32 (0x78, extentref_tree_type);
+ // G32 (0x7C, snap_meta_tree_type);
+
+ G64o (0x80, omap_oid);
+ G64o (0x88, root_tree_oid);
+ /*
+ G64o (0x90, extentref_tree_oid);
+ G64o (0x98, snap_meta_tree_oid);
+ G64x (0xa0, revert_to_xid);
+ G64o (0xa8, revert_to_sblock_oid);
+ G64 (0xb0, next_obj_id);
+ */
+ G64 (0xb8, num_files);
+ G64 (0xc0, num_directories);
+ G64 (0xc8, num_symlinks);
+ G64 (0xd0, num_other_fsobjects);
+ G64 (0xd8, num_snapshots);
+ G64 (0xe0, total_blocks_alloced);
+ G64 (0xe8, total_blocks_freed);
+ vol_uuid.SetFrom(p + 0xf0);
+ G64 (0x100, last_mod_time);
+ G64 (0x108, fs_flags);
+ p += 0x110;
+ formatted_by.Parse(p);
+ p += sizeof__apfs_modified_by_t;
+ for (unsigned i = 0; i < APFS_MAX_HIST; i++)
+ {
+ modified_by[i].Parse(p);
+ p += sizeof__apfs_modified_by_t;
+ }
+ memcpy(volname, p, APFS_VOLNAME_LEN);
+ p += APFS_VOLNAME_LEN;
+ /*
+ G32 (0, next_doc_id);
+ G16 (4, role);
+ G16 (6, reserved);
+ G64x (8, root_to_xid);
+ G64o (0x10, er_state_oid);
+ G64 (0x18, cloneinfo_id_epoch);
+ G64 (0x20, cloneinfo_xid);
+ G64o (0x28, snap_meta_ext_oid);
+ volume_group_id.SetFrom(p + 0x30);
+ G64o (0x40, integrity_meta_oid);
+ G64o (0x48, fext_tree_oid);
+ G32 (0x50, fext_tree_type);
+ G32 (0x54, reserved_type);
+ G64o (0x58, reserved_oid);
+ */
+ return true;
+}
+
+
+#define OBJ_ID_MASK 0x0fffffffffffffff
+/*
+#define OBJ_TYPE_MASK 0xf000000000000000
+#define SYSTEM_OBJ_ID_MARK 0x0fffffff00000000
+*/
+#define OBJ_TYPE_SHIFT 60
+
+typedef enum
+{
+ APFS_TYPE_ANY = 0,
+ APFS_TYPE_SNAP_METADATA = 1,
+ APFS_TYPE_EXTENT = 2,
+ APFS_TYPE_INODE = 3,
+ APFS_TYPE_XATTR = 4,
+ APFS_TYPE_SIBLING_LINK = 5,
+ APFS_TYPE_DSTREAM_ID = 6,
+ APFS_TYPE_CRYPTO_STATE = 7,
+ APFS_TYPE_FILE_EXTENT = 8,
+ APFS_TYPE_DIR_REC = 9,
+ APFS_TYPE_DIR_STATS = 10,
+ APFS_TYPE_SNAP_NAME = 11,
+ APFS_TYPE_SIBLING_MAP = 12,
+ APFS_TYPE_FILE_INFO = 13,
+ APFS_TYPE_MAX_VALID = 13,
+ APFS_TYPE_MAX = 15,
+ APFS_TYPE_INVALID = 15
+} j_obj_types;
+
+
+struct j_key_t
+{
+ UInt64 obj_id_and_type;
+
+ void Parse(const Byte *p) { G64(0, obj_id_and_type); }
+ unsigned GetType() const { return (unsigned)(obj_id_and_type >> OBJ_TYPE_SHIFT); }
+ UInt64 GetID() const { return obj_id_and_type & OBJ_ID_MASK; }
+};
+
+
+
+#define J_DREC_LEN_MASK 0x000003ff
+/*
+#define J_DREC_HASH_MASK 0xfffff400
+#define J_DREC_HASH_SHIFT 10
+*/
+
+static const unsigned k_SizeOf_j_drec_val = 0x12;
+
+struct j_drec_val
+{
+ UInt64 file_id;
+ UInt64 date_added; /* The time that this directory entry was added to the directory.
+ It's not updated when modifying the directory entry for example,
+ by renaming a file without moving it to a different directory. */
+ UInt16 flags;
+
+ // bool IsFlags_File() const { return flags == MY_LIN_DT_REG; }
+ bool IsFlags_Unknown() const { return flags == MY_LIN_DT_UNKNOWN; }
+ bool IsFlags_Dir() const { return flags == MY_LIN_DT_DIR; }
+
+ // uint8_t xfields[];
+ void Parse(const Byte *p)
+ {
+ G64 (0, file_id);
+ G64 (8, date_added);
+ G16 (0x10, flags);
+ }
+};
+
+
+struct CItem
+{
+ // j_key_t hdr;
+ UInt64 ParentId;
+ AString Name;
+ j_drec_val Val;
+
+ unsigned ParentItemIndex;
+ unsigned RefIndex;
+ // unsigned iNode_Index;
+
+ CItem():
+ ParentItemIndex(VI_MINUS1),
+ RefIndex(VI_MINUS1)
+ // iNode_Index(VI_MINUS1)
+ {}
+};
+
+
+/*
+#define INVALID_INO_NUM 0
+#define ROOT_DIR_PARENT 1 // parent for "root" and "private-dir", there's no inode on disk with this inode number.
+*/
+#define ROOT_DIR_INO_NUM 2 // "root" - parent for all main files
+#define PRIV_DIR_INO_NUM 3 // "private-dir"
+/*
+#define SNAP_DIR_INO_NUM 6 // the directory where snapshot metadata is stored. Snapshot inodes are stored in the snapshot metedata tree.
+#define PURGEABLE_DIR_INO_NUM 7
+#define MIN_USER_INO_NUM 16
+
+#define UNIFIED_ID_SPACE_MARK 0x0800000000000000
+*/
+
+/*
+typedef enum
+{
+INODE_IS_APFS_PRIVATE = 0x00000001,
+INODE_MAINTAIN_DIR_STATS = 0x00000002,
+INODE_DIR_STATS_ORIGIN = 0x00000004,
+INODE_PROT_CLASS_EXPLICIT = 0x00000008,
+INODE_WAS_CLONED = 0x00000010,
+INODE_FLAG_UNUSED = 0x00000020,
+INODE_HAS_SECURITY_EA = 0x00000040,
+INODE_BEING_TRUNCATED = 0x00000080,
+INODE_HAS_FINDER_INFO = 0x00000100,
+INODE_IS_SPARSE = 0x00000200,
+INODE_WAS_EVER_CLONED = 0x00000400,
+INODE_ACTIVE_FILE_TRIMMED = 0x00000800,
+INODE_PINNED_TO_MAIN = 0x00001000,
+INODE_PINNED_TO_TIER2 = 0x00002000,
+INODE_HAS_RSRC_FORK = 0x00004000,
+INODE_NO_RSRC_FORK = 0x00008000,
+INODE_ALLOCATION_SPILLEDOVER = 0x00010000,
+INODE_FAST_PROMOTE = 0x00020000,
+INODE_HAS_UNCOMPRESSED_SIZE = 0x00040000,
+INODE_IS_PURGEABLE = 0x00080000,
+INODE_WANTS_TO_BE_PURGEABLE = 0x00100000,
+INODE_IS_SYNC_ROOT = 0x00200000,
+INODE_SNAPSHOT_COW_EXEMPTION = 0x00400000,
+
+
+INODE_INHERITED_INTERNAL_FLAGS = \
+ ( INODE_MAINTAIN_DIR_STATS \
+ | INODE_SNAPSHOT_COW_EXEMPTION),
+
+INODE_CLONED_INTERNAL_FLAGS = \
+ ( INODE_HAS_RSRC_FORK \
+ | INODE_NO_RSRC_FORK \
+ | INODE_HAS_FINDER_INFO \
+ | INODE_SNAPSHOT_COW_EXEMPTION),
+}
+j_inode_flags;
+
+
+#define APFS_VALID_INTERNAL_INODE_FLAGS \
+( INODE_IS_APFS_PRIVATE \
+| INODE_MAINTAIN_DIR_STATS \
+| INODE_DIR_STATS_ORIGIN \
+| INODE_PROT_CLASS_EXPLICIT \
+| INODE_WAS_CLONED \
+| INODE_HAS_SECURITY_EA \
+| INODE_BEING_TRUNCATED \
+| INODE_HAS_FINDER_INFO \
+| INODE_IS_SPARSE \
+| INODE_WAS_EVER_CLONED \
+| INODE_ACTIVE_FILE_TRIMMED \
+| INODE_PINNED_TO_MAIN \
+| INODE_PINNED_TO_TIER2 \
+| INODE_HAS_RSRC_FORK \
+| INODE_NO_RSRC_FORK \
+| INODE_ALLOCATION_SPILLEDOVER \
+| INODE_FAST_PROMOTE \
+| INODE_HAS_UNCOMPRESSED_SIZE \
+| INODE_IS_PURGEABLE \
+| INODE_WANTS_TO_BE_PURGEABLE \
+| INODE_IS_SYNC_ROOT \
+| INODE_SNAPSHOT_COW_EXEMPTION)
+
+#define APFS_INODE_PINNED_MASK (INODE_PINNED_TO_MAIN | INODE_PINNED_TO_TIER2)
+*/
+
+static const char * const g_INODE_Flags[] =
+{
+ "IS_APFS_PRIVATE"
+ , "MAINTAIN_DIR_STATS"
+ , "DIR_STATS_ORIGIN"
+ , "PROT_CLASS_EXPLICIT"
+ , "WAS_CLONED"
+ , "FLAG_UNUSED"
+ , "HAS_SECURITY_EA"
+ , "BEING_TRUNCATED"
+ , "HAS_FINDER_INFO"
+ , "IS_SPARSE"
+ , "WAS_EVER_CLONED"
+ , "ACTIVE_FILE_TRIMMED"
+ , "PINNED_TO_MAIN"
+ , "PINNED_TO_TIER2"
+ , "HAS_RSRC_FORK"
+ , "NO_RSRC_FORK"
+ , "ALLOCATION_SPILLEDOVER"
+ , "FAST_PROMOTE"
+ , "HAS_UNCOMPRESSED_SIZE"
+ , "IS_PURGEABLE"
+ , "WANTS_TO_BE_PURGEABLE"
+ , "IS_SYNC_ROOT"
+ , "SNAPSHOT_COW_EXEMPTION"
+};
+
+
+// bsd stat.h
+/*
+#define MY__UF_SETTABLE 0x0000ffff // mask of owner changeable flags
+#define MY__UF_NODUMP 0x00000001 // do not dump file
+#define MY__UF_IMMUTABLE 0x00000002 // file may not be changed
+#define MY__UF_APPEND 0x00000004 // writes to file may only append
+#define MY__UF_OPAQUE 0x00000008 // directory is opaque wrt. union
+#define MY__UF_NOUNLINK 0x00000010 // file entry may not be removed or renamed Not implement in MacOS
+#define MY__UF_COMPRESSED 0x00000020 // file entry is compressed
+#define MY__UF_TRACKED 0x00000040 // notify about file entry changes
+#define MY__UF_DATAVAULT 0x00000080 // entitlement required for reading and writing
+#define MY__UF_HIDDEN 0x00008000 // file entry is hidden
+
+#define MY__SF_SETTABLE 0xffff0000 // mask of superuser changeable flags
+#define MY__SF_ARCHIVED 0x00010000 // file is archived
+#define MY__SF_IMMUTABLE 0x00020000 // file may not be changed
+#define MY__SF_APPEND 0x00040000 // writes to file may only append
+#define MY__SF_RESTRICTED 0x00080000 // entitlement required for writing
+#define MY__SF_NOUNLINK 0x00100000 // file entry may not be removed, renamed or used as mount point
+#define MY__SF_SNAPSHOT 0x00200000 // snapshot inode
+Not implement in MacOS
+*/
+
+static const char * const g_INODE_BSD_Flags[] =
+{
+ "UF_NODUMP"
+ , "UF_IMMUTABLE"
+ , "UF_APPEND"
+ , "UF_OPAQUE"
+ , "UF_NOUNLINK"
+ , "UF_COMPRESSED"
+ , "UF_TRACKED"
+ , "UF_DATAVAULT"
+ , NULL, NULL, NULL, NULL
+ , NULL, NULL, NULL
+ , "UF_HIDDEN"
+
+ , "SF_ARCHIVE"
+ , "SF_IMMUTABLE"
+ , "SF_APPEND"
+ , "SF_RESTRICTED"
+ , "SF_NOUNLINK"
+ , "SF_SNAPSHOT"
+};
+
+/*
+#define INO_EXT_TYPE_SNAP_XID 1
+#define INO_EXT_TYPE_DELTA_TREE_OID 2
+#define INO_EXT_TYPE_DOCUMENT_ID 3
+*/
+#define INO_EXT_TYPE_NAME 4
+/*
+#define INO_EXT_TYPE_PREV_FSIZE 5
+#define INO_EXT_TYPE_RESERVED_6 6
+#define INO_EXT_TYPE_FINDER_INFO 7
+*/
+#define INO_EXT_TYPE_DSTREAM 8
+/*
+#define INO_EXT_TYPE_RESERVED_9 9
+#define INO_EXT_TYPE_DIR_STATS_KEY 10
+#define INO_EXT_TYPE_FS_UUID 11
+#define INO_EXT_TYPE_RESERVED_12 12
+#define INO_EXT_TYPE_SPARSE_BYTES 13
+#define INO_EXT_TYPE_RDEV 14
+#define INO_EXT_TYPE_PURGEABLE_FLAGS 15
+#define INO_EXT_TYPE_ORIG_SYNC_ROOT_ID 16
+*/
+
+
+static const unsigned k_SizeOf_j_dstream = 8 * 5;
+
+struct j_dstream
+{
+ UInt64 size;
+ UInt64 alloced_size;
+ UInt64 default_crypto_id;
+ UInt64 total_bytes_written;
+ UInt64 total_bytes_read;
+
+ void Parse(const Byte *p)
+ {
+ G64 (0, size);
+ G64 (0x8, alloced_size);
+ G64 (0x10, default_crypto_id);
+ G64 (0x18, total_bytes_written);
+ G64 (0x20, total_bytes_read);
+ }
+};
+
+static const unsigned k_SizeOf_j_file_extent_val = 8 * 3;
+
+#define J_FILE_EXTENT_LEN_MASK 0x00ffffffffffffffU
+// #define J_FILE_EXTENT_FLAG_MASK 0xff00000000000000U
+// #define J_FILE_EXTENT_FLAG_SHIFT 56
+
+#define EXTENT_GET_LEN(x) ((x) & J_FILE_EXTENT_LEN_MASK)
+
+struct j_file_extent_val
+{
+ UInt64 len_and_flags; // The length must be a multiple of the block size defined by the nx_block_size field of nx_superblock_t.
+ // There are currently no flags defined
+ UInt64 phys_block_num; // The physical block address that the extent starts at
+ // UInt64 crypto_id; // The encryption key or the encryption tweak used in this extent.
+
+ void Parse(const Byte *p)
+ {
+ G64 (0, len_and_flags);
+ G64 (0x8, phys_block_num);
+ // G64 (0x10, crypto_id);
+ }
+};
+
+
+struct CExtent
+{
+ UInt64 logical_offset;
+ UInt64 len_and_flags; // The length must be a multiple of the block size defined by the nx_block_size field of nx_superblock_t.
+ // There are currently no flags defined
+ UInt64 phys_block_num; // The physical block address that the extent starts at
+};
+
+
+typedef UInt32 MY__uid_t;
+typedef UInt32 MY__gid_t;
+typedef UInt16 MY__mode_t;
+
+
+typedef enum
+{
+ XATTR_DATA_STREAM = 1 << 0,
+ XATTR_DATA_EMBEDDED = 1 << 1,
+ XATTR_FILE_SYSTEM_OWNED = 1 << 2,
+ XATTR_RESERVED_8 = 1 << 3
+} j_xattr_flags;
+
+
+struct CAttr
+{
+ AString Name;
+ UInt32 flags;
+ CByteBuffer Data;
+
+ j_dstream dstream;
+ bool dstream_defined;
+ UInt64 Id;
+
+ bool Is_dstream_OK_for_SymLink() const
+ {
+ return dstream_defined && dstream.size <= (1 << 12) && dstream.size != 0;
+ }
+
+ CAttr():
+ dstream_defined(false)
+ {}
+
+ bool Is_STREAM() const { return (flags & XATTR_DATA_STREAM) != 0; }
+ bool Is_EMBEDDED() const { return (flags & XATTR_DATA_EMBEDDED) != 0; }
+};
+
+
+// j_inode_val_t
+struct CNode
+{
+ unsigned ItemIndex; // index to CItem. We set it only if Node is directory.
+ unsigned NumCalcedLinks; // Num links to that node
+ // unsigned NumItems; // Num Items in that node
+
+ UInt64 parent_id; // The identifier of the file system record for the parent directory.
+ UInt64 private_id;
+ UInt64 create_time;
+ UInt64 mod_time;
+ UInt64 change_time;
+ UInt64 access_time;
+ UInt64 internal_flags;
+ union
+ {
+ UInt32 nchildren; /* The number of directory entries.
+ is valid only if the inode is a directory */
+ UInt32 nlink; /* The number of hard links whose target is this inode.
+ is valid only if the inode isn't a directory.
+ Inodes with multiple hard links (nlink > 1)
+ - The parent_id field refers to the parent directory of the primary link.
+ - The name field contains the name of the primary link.
+ - The INO_EXT_TYPE_NAME extended field contains the name of this link.
+ */
+ };
+ // cp_key_class_t default_protection_class;
+ UInt32 write_generation_counter;
+ UInt32 bsd_flags;
+ MY__uid_t owner;
+ MY__gid_t group;
+ MY__mode_t mode;
+ UInt16 pad1;
+ // UInt64 uncompressed_size;
+
+ j_dstream dstream;
+ AString PrimaryName;
+ bool dstream_defined;
+ bool refcnt_defined;
+ UInt32 refcnt; // j_dstream_id_val_t
+ CRecordVector<CExtent> Extents;
+ CObjectVector<CAttr> Attrs;
+ unsigned SymLinkIndex; // index in Attrs
+
+ CNode():
+ ItemIndex(VI_MINUS1),
+ NumCalcedLinks(0),
+ // NumItems(0),
+ dstream_defined(false),
+ refcnt_defined(false),
+ SymLinkIndex(VI_MINUS1)
+ {}
+
+ bool IsDir() const { return MY_LIN_S_ISDIR(mode); }
+ bool IsSymLink() const { return MY_LIN_S_ISLNK(mode); }
+ unsigned Get_Type_From_mode() const { return mode >> 12; }
+
+ bool GetSize(unsigned attrIndex, UInt64 &size) const
+ {
+ if (IsViNotDef(attrIndex))
+ {
+ if (dstream_defined)
+ {
+ size = dstream.size;
+ return true;
+ }
+ if (!IsSymLink())
+ return false;
+ attrIndex = SymLinkIndex;
+ if (IsViNotDef(attrIndex))
+ return false;
+ }
+ const CAttr &attr = Attrs[(unsigned)attrIndex];
+ if (attr.dstream_defined)
+ size = attr.dstream.size;
+ else
+ size = attr.Data.Size();
+ return true;
+ }
+
+ bool GetPackSize(unsigned attrIndex, UInt64 &size) const
+ {
+ if (IsViNotDef(attrIndex))
+ {
+ if (dstream_defined)
+ {
+ size = dstream.alloced_size;
+ return true;
+ }
+ if (!IsSymLink())
+ return false;
+ attrIndex = SymLinkIndex;
+ if (IsViNotDef(attrIndex))
+ return false;
+ }
+ const CAttr &attr = Attrs[(unsigned)attrIndex];
+ if (attr.dstream_defined)
+ size = attr.dstream.alloced_size;
+ else
+ size = attr.Data.Size();
+ return true;
+ }
+
+ void Parse(const Byte *p);
+};
+
+
+// it's used for Attr streams
+struct CSmallNode
+{
+ CRecordVector<CExtent> Extents;
+ // UInt32 NumLinks;
+ // CSmallNode(): NumLinks(0) {};
+};
+
+static const unsigned k_SizeOf_j_inode_val = 0x5c;
+
+void CNode::Parse(const Byte *p)
+{
+ G64 (0, parent_id);
+ G64 (0x8, private_id);
+ G64 (0x10, create_time);
+ G64 (0x18, mod_time);
+ G64 (0x20, change_time);
+ G64 (0x28, access_time);
+ G64 (0x30, internal_flags);
+ {
+ G32(0x38, nchildren);
+ // G32(0x38, nlink);
+ }
+ // G32(0x3c, default_protection_class);
+ G32(0x40, write_generation_counter);
+ G32(0x44, bsd_flags);
+ G32(0x48, owner);
+ G32(0x4c, group);
+ G16(0x50, mode);
+ // G16(0x52, pad1);
+ // G64 (0x54, uncompressed_size);
+}
+
+
+struct CRef
+{
+ unsigned ItemIndex;
+ unsigned NodeIndex;
+ unsigned ParentRefIndex;
+
+ #ifdef APFS_SHOW_ALT_STREAMS
+ unsigned AttrIndex;
+ bool IsAltStream() const { return IsViDef(AttrIndex); }
+ unsigned GetAttrIndex() const { return AttrIndex; };
+ #else
+ unsigned GetAttrIndex() const { return VI_MINUS1; };
+ #endif
+};
+
+
+struct CRef2
+{
+ unsigned VolIndex;
+ unsigned RefIndex;
+};
+
+
+struct CVol
+{
+ CObjectVector<CNode> Nodes;
+ CRecordVector<UInt64> NodeIDs;
+ CObjectVector<CItem> Items;
+ CRecordVector<CRef> Refs;
+
+ CObjectVector<CSmallNode> SmallNodes;
+ CRecordVector<UInt64> SmallNodeIDs;
+
+ unsigned StartRef2Index; // ref2_Index for Refs[0] item
+ unsigned RootRef2Index; // ref2_Index of virtual root folder (Volume1)
+ CApfs apfs;
+ bool NodeNotFound;
+ bool ThereAreUnlinkedNodes;
+ bool WrongInodeLink;
+ bool UnsupportedFeature;
+
+ unsigned NumItems_In_PrivateDir;
+ unsigned NumAltStreams;
+
+ UString RootName;
+
+ bool ThereAreErrors() const
+ {
+ return NodeNotFound || ThereAreUnlinkedNodes || WrongInodeLink;
+ }
+
+ void AddComment(UString &s) const;
+
+ HRESULT FillRefs();
+
+ CVol():
+ StartRef2Index(0),
+ RootRef2Index(VI_MINUS1),
+ NodeNotFound(false),
+ ThereAreUnlinkedNodes(false),
+ WrongInodeLink(false),
+ UnsupportedFeature(false),
+ NumItems_In_PrivateDir(0),
+ NumAltStreams(0)
+ {}
+};
+
+
+static void ApfsTimeToFileTime(UInt64 apfsTime, FILETIME &ft, UInt32 &ns100)
+{
+ const UInt64 s = apfsTime / 1000000000;
+ const UInt32 ns = (UInt32)(apfsTime % 1000000000);
+ ns100 = (ns % 100);
+ const UInt64 v = NWindows::NTime::UnixTime64_To_FileTime64(s) + ns / 100;
+ ft.dwLowDateTime = (DWORD)v;
+ ft.dwHighDateTime = (DWORD)(v >> 32);
+}
+
+static void AddComment_Name(UString &s, const char *name)
+{
+ s += name;
+ s += ": ";
+}
+
+/*
+static void AddComment_Bool(UString &s, const char *name, bool val)
+{
+ AddComment_Name(s, name);
+ s += val ? "+" : "-";
+ s.Add_LF();
+}
+*/
+
+static void AddComment_UInt64(UString &s, const char *name, UInt64 v)
+{
+ AddComment_Name(s, name);
+ s.Add_UInt64(v);
+ s.Add_LF();
+}
+
+
+static void AddComment_Time(UString &s, const char *name, UInt64 v)
+{
+ AddComment_Name(s, name);
+
+ FILETIME ft;
+ UInt32 ns100;
+ ApfsTimeToFileTime(v, ft, ns100);
+ char temp[64];
+ ConvertUtcFileTimeToString2(ft, ns100, temp
+ // , kTimestampPrintLevel_SEC);
+ , kTimestampPrintLevel_NS);
+ s += temp;
+ s.Add_LF();
+}
+
+
+static void AddComment_modified_by_t(UString &s, const char *name, const apfs_modified_by_t &v)
+{
+ AddComment_Name(s, name);
+ AString s2;
+ s2.SetFrom_CalcLen((const char *)v.id, sizeof(v.id));
+ s += s2;
+ s.Add_LF();
+ s += " ";
+ AddComment_Time(s, "timestamp", v.timestamp);
+ s += " ";
+ AddComment_UInt64(s, "last_xid", v.last_xid);
+}
+
+
+static void AddVolInternalName_toString(UString &s, const CApfs &apfs)
+{
+ AString temp;
+ temp.SetFrom_CalcLen((const char *)apfs.volname, sizeof(apfs.volname));
+ UString unicode;
+ ConvertUTF8ToUnicode(temp, unicode);
+ s += unicode;
+}
+
+
+void CVol::AddComment(UString &s) const
+{
+ AddComment_UInt64(s, "fs_index", apfs.fs_index);
+ {
+ AddComment_Name(s, "volume_name");
+ AddVolInternalName_toString(s, apfs);
+ s.Add_LF();
+ }
+ AddComment_Name(s, "vol_uuid");
+ apfs.vol_uuid.AddHexToString(s);
+ s.Add_LF();
+
+ AddComment_Name(s, "incompatible_features");
+ s += FlagsToString(g_APFS_INCOMPAT_Flags,
+ ARRAY_SIZE(g_APFS_INCOMPAT_Flags),
+ (UInt32)apfs.incompatible_features);
+ s.Add_LF();
+
+ // AddComment_UInt64(s, "reserve_block_count", apfs.fs_reserve_block_count, false);
+ // AddComment_UInt64(s, "quota_block_count", apfs.fs_quota_block_count);
+ AddComment_UInt64(s, "fs_alloc_count", apfs.fs_alloc_count);
+
+ AddComment_UInt64(s, "num_files", apfs.num_files);
+ AddComment_UInt64(s, "num_directories", apfs.num_directories);
+ AddComment_UInt64(s, "num_symlinks", apfs.num_symlinks);
+ AddComment_UInt64(s, "num_other_fsobjects", apfs.num_other_fsobjects);
+
+ AddComment_UInt64(s, "Num_Attr_Streams", NumAltStreams);
+
+ AddComment_UInt64(s, "num_snapshots", apfs.num_snapshots);
+ AddComment_UInt64(s, "total_blocks_alloced", apfs.total_blocks_alloced);
+ AddComment_UInt64(s, "total_blocks_freed", apfs.total_blocks_freed);
+
+ AddComment_Time(s, "unmounted", apfs.unmount_time);
+ AddComment_Time(s, "last_modified", apfs.last_mod_time);
+ AddComment_modified_by_t(s, "formatted_by", apfs.formatted_by);
+ for (unsigned i = 0; i < ARRAY_SIZE(apfs.modified_by); i++)
+ {
+ const apfs_modified_by_t &v = apfs.modified_by[i];
+ if (v.last_xid == 0 && v.timestamp == 0 && v.id[0] == 0)
+ continue;
+ AString name ("modified_by[");
+ name.Add_UInt32(i);
+ name += ']';
+ AddComment_modified_by_t(s, name.Ptr(), v);
+ }
+}
+
+
+
+struct CKeyValPair
+{
+ CByteBuffer Key;
+ CByteBuffer Val;
+ // unsigned ValPos; // for alognment
+};
+
+
+struct omap_key
+{
+ oid_t oid; // The object identifier
+ xid_t xid; // The transaction identifier
+ void Parse(const Byte *p)
+ {
+ G64o (0, oid);
+ G64x (8, xid);
+ }
+};
+
+/*
+#define OMAP_VAL_DELETED (1 << 0)
+#define OMAP_VAL_SAVED (1 << 1)
+#define OMAP_VAL_ENCRYPTED (1 << 2)
+#define OMAP_VAL_NOHEADER (1 << 3)
+#define OMAP_VAL_CRYPTO_GENERATION (1 << 4)
+*/
+
+struct omap_val
+{
+ UInt32 flags;
+ UInt32 size;
+ paddr_t paddr;
+
+ void Parse(const Byte *p)
+ {
+ G32 (0, flags);
+ G32 (4, size);
+ G64 (8, paddr);
+ }
+};
+
+
+struct CObjectMap
+{
+ CRecordVector<UInt64> Keys;
+ CRecordVector<omap_val> Vals;
+
+ bool Parse(const CObjectVector<CKeyValPair> &pairs);
+ int FindKey(UInt64 id) const { return Keys.FindInSorted(id); }
+};
+
+bool CObjectMap::Parse(const CObjectVector<CKeyValPair> &pairs)
+{
+ omap_key prev;
+ prev.oid = 0;
+ prev.xid = 0;
+ FOR_VECTOR (i, pairs)
+ {
+ const CKeyValPair &pair = pairs[i];
+ if (pair.Key.Size() != 16 || pair.Val.Size() != 16)
+ return false;
+ omap_key key;
+ key.Parse(pair.Key);
+ omap_val val;
+ val.Parse(pair.Val);
+ /* Object map B-trees are sorted by object identifier and then by transaction identifier
+ but it's possible to have identical Ids in map ?
+ do we need to look transaction id ?
+ and search key with largest transaction id? */
+ if (key.oid <= prev.oid)
+ return false;
+ prev = key;
+ Keys.Add(key.oid);
+ Vals.Add(val);
+ }
+ return true;
+}
+
+
+struct CMap
+{
+ CObjectVector<CKeyValPair> Pairs;
+
+ CObjectMap Omap;
+ btree_info bti;
+ UInt64 NumNodes;
+
+ // we use thnese options to check:
+ UInt32 Subtype;
+ bool IsPhysical;
+
+ bool CheckAtFinish() const
+ {
+ return NumNodes == bti.node_count && Pairs.Size() == bti.key_count;
+ }
+
+ CMap():
+ NumNodes(0),
+ Subtype(0),
+ IsPhysical(true)
+ {}
+};
+
+
+
+struct CDatabase
+{
+ CRecordVector<CRef2> Refs2;
+ CObjectVector<CVol> Vols;
+
+ bool HeadersError;
+ bool ThereAreAltStreams;
+ bool UnsupportedFeature;
+
+ CSuperBlock sb;
+
+ IInStream *OpenInStream;
+ IArchiveOpenCallback *OpenCallback;
+ UInt64 ProgressVal_Cur;
+ UInt64 ProgressVal_Prev;
+ UInt64 ProgressVal_NumFilesTotal;
+ CObjectVector<CByteBuffer> Buffers;
+
+ UInt64 GetSize(const UInt32 index) const;
+
+ void Clear()
+ {
+ HeadersError = false;
+ UnsupportedFeature = false;
+ ThereAreAltStreams = false;
+
+ ProgressVal_Cur = 0;
+ ProgressVal_Prev = 0;
+ ProgressVal_NumFilesTotal = 0;
+
+ Vols.Clear();
+ Refs2.Clear();
+ Buffers.Clear();
+ }
+
+ HRESULT SeekReadBlock_FALSE(UInt64 oid, void *data);
+ void GetItemPath(unsigned index, const CNode *inode, NWindows::NCOM::CPropVariant &path) const;
+ HRESULT ReadMap(UInt64 oid, CMap &map, unsigned recurseLevel);
+ HRESULT ReadObjectMap(UInt64 oid, CObjectMap &map);
+ HRESULT OpenVolume(const CObjectMap &omap, const oid_t fs_oid);
+ HRESULT Open2();
+
+ HRESULT GetStream2(
+ IInStream *apfsInStream,
+ const CRecordVector<CExtent> *extents, UInt64 rem,
+ ISequentialInStream **stream);
+};
+
+
+HRESULT CDatabase::SeekReadBlock_FALSE(UInt64 oid, void *data)
+{
+ if (OpenCallback)
+ {
+ if (ProgressVal_Cur - ProgressVal_Prev >= (1 << 22))
+ {
+ RINOK(OpenCallback->SetCompleted(NULL, &ProgressVal_Cur));
+ ProgressVal_Prev = ProgressVal_Cur;
+ }
+ ProgressVal_Cur += sb.block_size;
+ }
+ if (oid == 0 || oid >= sb.block_count)
+ return S_FALSE;
+ RINOK(OpenInStream->Seek(oid << sb.block_size_Log, STREAM_SEEK_SET, NULL));
+ return ReadStream_FALSE(OpenInStream, data, sb.block_size);
+}
+
+
+
+API_FUNC_static_IsArc IsArc_APFS(const Byte *p, size_t size)
+{
+ if (size < kApfsHeaderSize)
+ return k_IsArc_Res_NEED_MORE;
+ CSuperBlock sb;
+ if (!sb.Parse(p))
+ return k_IsArc_Res_NO;
+ return k_IsArc_Res_YES;
+}
+}
+
+
+
+HRESULT CDatabase::ReadMap(UInt64 oid, CMap &map, unsigned recurseLevel)
+{
+ // is it allowed to use big number of levels ?
+ if (recurseLevel > (1 << 10))
+ return S_FALSE;
+
+ const UInt32 blockSize = sb.block_size;
+ if (Buffers.Size() <= recurseLevel)
+ {
+ Buffers.AddNew();
+ if (Buffers.Size() <= recurseLevel)
+ throw 123;
+ Buffers.Back().Alloc(blockSize);
+ }
+ const Byte *buf;
+ {
+ CByteBuffer &buf2 = Buffers[recurseLevel];
+ RINOK(SeekReadBlock_FALSE(oid, buf2));
+ buf = buf2;
+ }
+
+ CBTreeNodePhys bt;
+ if (!bt.Parse(buf, blockSize))
+ return S_FALSE;
+
+ map.NumNodes++;
+
+ /* Specification: All values are stored in leaf nodes, which
+ makes these B+ trees, and the values in nonleaf nodes are object
+ identifiers of child nodes.
+
+ The entries in the table of contents are sorted by key. The comparison function used for sorting depends on the keys type
+ - Object map B-trees are sorted by object identifier and then by transaction identifier.
+ - Free queue B-trees are sorted by transaction identifier and then by physical address.
+ - File-system records are sorted according to the rules listed in File-System Objects.
+ */
+
+ if (bt.o.subtype != map.Subtype)
+ return S_FALSE;
+
+ unsigned endLimit = blockSize;
+
+ if (recurseLevel == 0)
+ {
+ if (bt.o.GetType() != OBJECT_TYPE_BTREE)
+ return S_FALSE;
+ if ((bt.flags & BTNODE_ROOT) == 0)
+ return S_FALSE;
+ endLimit -= k_btree_info_Size;
+ map.bti.Parse(buf + endLimit);
+ btree_info &bti = map.bti;
+ if (bti.fixed.key_size >= blockSize)
+ return S_FALSE;
+ if (bti.Is_EPHEMERAL() &&
+ bti.Is_PHYSICAL())
+ return S_FALSE;
+ if (bti.Is_PHYSICAL() != map.IsPhysical)
+ return S_FALSE;
+ // we don't allow volumes with big number of Keys
+ const UInt32 kNumItemsMax = k_VectorSizeMax;
+ if (map.bti.node_count > kNumItemsMax)
+ return S_FALSE;
+ if (map.bti.key_count > kNumItemsMax)
+ return S_FALSE;
+ }
+ else
+ {
+ if (bt.o.GetType() != OBJECT_TYPE_BTREE_NODE)
+ return S_FALSE;
+ if ((bt.flags & BTNODE_ROOT) != 0)
+ return S_FALSE;
+ if (map.NumNodes > map.bti.node_count
+ || map.Pairs.Size() > map.bti.key_count)
+ return S_FALSE;
+ }
+
+ const bool isLeaf = (bt.flags & BTNODE_LEAF) != 0;
+
+ if (isLeaf)
+ {
+ if (bt.level != 0)
+ return S_FALSE;
+ }
+ else
+ {
+ if (bt.level == 0)
+ return S_FALSE;
+ }
+
+ if (!bt.table_space.CheckOverLimit(endLimit - k_Toc_offset))
+ return S_FALSE;
+
+ const unsigned tableEnd = k_Toc_offset + bt.table_space.GetEnd();
+ const unsigned keyValRange = endLimit - tableEnd;
+ const unsigned tocEntrySize = bt.Is_FIXED_KV_SIZE() ? 4 : 8;
+ if (bt.table_space.len / tocEntrySize < bt.nkeys)
+ return S_FALSE;
+
+ for (unsigned i = 0; i < bt.nkeys; i++)
+ {
+ const Byte *p = buf + k_Toc_offset + bt.table_space.off + i * tocEntrySize;
+ if (bt.Is_FIXED_KV_SIZE())
+ {
+ kvoff a;
+ a.Parse(p);
+ if (a.k + map.bti.fixed.key_size > keyValRange
+ || a.v > keyValRange)
+ return S_FALSE;
+ {
+ CKeyValPair pair;
+
+ const Byte *p2 = buf + k_Toc_offset + bt.table_space.len;
+ p2 += a.k;
+ pair.Key.CopyFrom(p2, map.bti.fixed.key_size);
+
+ p2 = buf + endLimit;
+ p2 -= a.v;
+ if (isLeaf)
+ {
+ if (a.v < map.bti.fixed.val_size)
+ return S_FALSE;
+ pair.Val.CopyFrom(p2, map.bti.fixed.val_size);
+ // pair.ValPos = endLimit - a.v;
+ map.Pairs.Add(pair);
+ continue;
+ }
+ {
+ if (a.v < 8)
+ return S_FALSE;
+ // value is only 64-bit for non leaf.
+ const oid_t oidNext = Get64(p2);
+ if (map.bti.Is_PHYSICAL())
+ {
+ RINOK(ReadMap(oidNext, map, recurseLevel + 1));
+ continue;
+ }
+ else
+ {
+ // fixme
+ return S_FALSE;
+ }
+ }
+ }
+ }
+ else
+ {
+ kvloc a;
+ a.Parse(p);
+ if (!a.k.CheckOverLimit(keyValRange)
+ || a.v.off > keyValRange
+ || a.v.len > a.v.off)
+ return S_FALSE;
+ {
+ CKeyValPair pair;
+ const Byte *p2 = buf + k_Toc_offset + bt.table_space.len;
+ p2 += a.k.off;
+ pair.Key.CopyFrom(p2, a.k.len);
+
+ p2 = buf + endLimit;
+ p2 -= a.v.off;
+ if (isLeaf)
+ {
+ pair.Val.CopyFrom(p2, a.v.len);
+ // pair.ValPos = endLimit - a.v.off;
+ map.Pairs.Add(pair);
+ continue;
+ }
+ {
+ if (a.v.off < 8 || a.v.len != 8)
+ return S_FALSE;
+ // value is only 64-bit for non leaf.
+ const oid_t oidNext = Get64(p2);
+
+ if (map.bti.Is_PHYSICAL())
+ {
+ return S_FALSE;
+ // the code was not tested:
+ // RINOK(ReadMap(oidNext, map, recurseLevel + 1));
+ // continue;
+ }
+ else
+ {
+ const int index = map.Omap.FindKey(oidNext);
+ if (index == -1)
+ return S_FALSE;
+ const omap_val &ov = map.Omap.Vals[(unsigned)index];
+ if (ov.size != blockSize) // change it : it must be multiple of
+ return S_FALSE;
+ RINOK(ReadMap(ov.paddr, map, recurseLevel + 1));
+ continue;
+ }
+ }
+ }
+ }
+ }
+
+ if (recurseLevel == 0)
+ if (!map.CheckAtFinish())
+ return S_FALSE;
+ return S_OK;
+}
+
+
+
+HRESULT CDatabase::ReadObjectMap(UInt64 oid, CObjectMap &omap)
+{
+ CByteBuffer buf;
+ const size_t blockSize = sb.block_size;
+ buf.Alloc(blockSize);
+ RINOK(SeekReadBlock_FALSE(oid, buf));
+ C_omap_phys op;
+ if (!op.Parse(buf, blockSize, oid))
+ return S_FALSE;
+ CMap map;
+ map.Subtype = OBJECT_TYPE_OMAP;
+ map.IsPhysical = true;
+ RINOK(ReadMap(op.tree_oid, map, 0));
+ if (!omap.Parse(map.Pairs))
+ return S_FALSE;
+ return S_OK;
+}
+
+
+
+HRESULT CDatabase::Open2()
+{
+ Clear();
+ CSuperBlock2 sb2;
+ {
+ Byte buf[kApfsHeaderSize];
+ RINOK(ReadStream_FALSE(OpenInStream, buf, kApfsHeaderSize));
+ if (!sb.Parse(buf))
+ return S_FALSE;
+ sb2.Parse(buf);
+ }
+
+ {
+ CObjectMap omap;
+ RINOK(ReadObjectMap(sb.omap_oid, omap));
+ unsigned numRefs = 0;
+ for (unsigned i = 0; i < sb.max_file_systems; i++)
+ {
+ const oid_t oid = sb2.fs_oid[i];
+ if (oid == 0)
+ continue;
+ // for (unsigned k = 0; k < 1; k++) // for debug
+ RINOK(OpenVolume(omap, oid));
+ const unsigned a = Vols.Back().Refs.Size();
+ numRefs += a;
+ if (numRefs < a)
+ return S_FALSE; // overflow
+ }
+ }
+
+ const bool needVolumePrefix = (Vols.Size() > 1);
+ // const bool needVolumePrefix = true; // for debug
+ {
+ unsigned numRefs = 0;
+ FOR_VECTOR (i, Vols)
+ {
+ const unsigned a = Vols[i].Refs.Size();
+ numRefs += a;
+ if (numRefs < a)
+ return S_FALSE; // overflow
+ }
+ numRefs += Vols.Size();
+ if (numRefs < Vols.Size())
+ return S_FALSE; // overflow
+ Refs2.Reserve(numRefs);
+ }
+ {
+ FOR_VECTOR (i, Vols)
+ {
+ CVol &vol = Vols[i];
+
+ CRef2 ref2;
+ ref2.VolIndex = i;
+
+ if (needVolumePrefix)
+ {
+ vol.RootName = "Volume";
+ vol.RootName.Add_UInt32(1 + (UInt32)i);
+ vol.RootRef2Index = Refs2.Size();
+ ref2.RefIndex = VI_MINUS1;
+ Refs2.Add(ref2);
+ }
+
+ vol.StartRef2Index = Refs2.Size();
+ const unsigned numItems = vol.Refs.Size();
+ for (unsigned k = 0; k < numItems; k++)
+ {
+ ref2.RefIndex = k;
+ Refs2.Add(ref2);
+ }
+ }
+ }
+ return S_OK;
+}
+
+
+HRESULT CDatabase::OpenVolume(const CObjectMap &omap, const oid_t fs_oid)
+{
+ const size_t blockSize = sb.block_size;
+ CByteBuffer buf;
+ {
+ const int index = omap.FindKey(fs_oid);
+ if (index == -1)
+ return S_FALSE;
+ const omap_val &ov = omap.Vals[(unsigned)index];
+ if (ov.size != blockSize) // change it : it must be multiple of
+ return S_FALSE;
+ buf.Alloc(blockSize);
+ RINOK(SeekReadBlock_FALSE(ov.paddr, buf));
+ }
+
+ CVol &vol = Vols.AddNew();
+ CApfs &apfs = vol.apfs;
+
+ if (!apfs.Parse(buf, blockSize))
+ return S_FALSE;
+
+ /* For each volume, read the root file system tree's virtual object
+ identifier from the apfs_root_tree_oid field,
+ and then look it up in the volume object map indicated
+ by the omap_oid field. */
+
+ CMap map;
+ {
+ ReadObjectMap(apfs.omap_oid, map.Omap);
+ const int index = map.Omap.FindKey(apfs.root_tree_oid);
+ if (index == -1)
+ return S_FALSE;
+ const omap_val &ov = map.Omap.Vals[(unsigned)index];
+ if (ov.size != blockSize) // change it : it must be multiple of
+ return S_FALSE;
+ map.Subtype = OBJECT_TYPE_FSTREE;
+ map.IsPhysical = false;
+ RINOK(ReadMap(ov.paddr, map, 0));
+ }
+
+ bool NeedReadSymLink = false;
+
+ {
+ const bool isHashed = apfs.IsHashedName();
+ UInt64 prevId = 1;
+
+ {
+ const UInt64 numApfsItems = vol.apfs.GetTotalItems()
+ + 2; // we will have 2 additional hidden directories: root and private-dir
+ const UInt64 numApfsItems_Reserve = numApfsItems
+ + 16; // we reserve 16 for some possible unexpected items
+ if (numApfsItems_Reserve < map.Pairs.Size())
+ {
+ vol.Items.ClearAndReserve((unsigned)numApfsItems_Reserve);
+ vol.Nodes.ClearAndReserve((unsigned)numApfsItems_Reserve);
+ vol.NodeIDs.ClearAndReserve((unsigned)numApfsItems_Reserve);
+ }
+ if (OpenCallback)
+ {
+ const UInt64 numFiles = ProgressVal_NumFilesTotal + numApfsItems;
+ RINOK(OpenCallback->SetTotal(&numFiles, NULL));
+ }
+ }
+
+ FOR_VECTOR (i, map.Pairs)
+ {
+ if (OpenCallback && (i & 0xffff) == 1)
+ {
+ const UInt64 numFiles = ProgressVal_NumFilesTotal +
+ (vol.Items.Size() + vol.Nodes.Size()) / 2;
+ RINOK(OpenCallback->SetCompleted(&numFiles, &ProgressVal_Cur));
+ }
+
+ const CKeyValPair &pair = map.Pairs[i];
+ j_key_t jkey;
+ if (pair.Key.Size() < 8)
+ return S_FALSE;
+ const Byte *p = pair.Key;
+ jkey.Parse(p);
+ const unsigned type = jkey.GetType();
+ const UInt64 id = jkey.GetID();
+ if (id < prevId)
+ return S_FALSE; // IDs must be sorted
+ prevId = id;
+
+ PRF(printf("\n%6d: id=%6d type = %2d", i, (unsigned)id, type));
+
+ if (type == APFS_TYPE_INODE)
+ {
+ PRF(printf (" INODE"));
+ if (pair.Key.Size() != 8 ||
+ pair.Val.Size() < k_SizeOf_j_inode_val)
+ return S_FALSE;
+
+ CNode inode;
+ inode.Parse(pair.Val);
+
+ if (inode.private_id != id)
+ {
+ /* private_id : The unique identifier used by this file's data stream.
+ This identifier appears in the owning_obj_id field of j_phys_ext_val_t
+ records that describe the extents where the data is stored.
+ For an inode that doesn't have data, the value of this
+ field is the file-system object's identifier.
+ */
+ // APFS_TYPE_EXTENT allow to link physical address extents.
+ // we don't support case (private_id != id)
+ UnsupportedFeature = true;
+ // return S_FALSE;
+ }
+ const UInt32 extraSize = (UInt32)pair.Val.Size() - k_SizeOf_j_inode_val;
+ if (extraSize != 0)
+ {
+ if (extraSize < 4)
+ return S_FALSE;
+ /*
+ struct xf_blob
+ {
+ uint16_t xf_num_exts;
+ uint16_t xf_used_data;
+ uint8_t xf_data[];
+ };
+ */
+ const Byte *p2 = pair.Val + k_SizeOf_j_inode_val;
+ const UInt32 xf_num_exts = Get16(p2);
+ const UInt32 xf_used_data = Get16(p2 + 2);
+ UInt32 offset = 4 + (UInt32)xf_num_exts * 4;
+ if (offset + xf_used_data != extraSize)
+ return S_FALSE;
+ for (unsigned k = 0; k < xf_num_exts; k++)
+ {
+ // struct x_field
+ const Byte *p3 = p2 + 4 + k * 4;
+ const Byte x_type = p3[0];
+ // const Byte x_flags = p3[1];
+ const UInt32 x_size = Get16(p3 + 2);
+ const UInt32 x_size_ceil = (x_size + 7) & ~(UInt32)7;
+ if (offset + x_size_ceil > extraSize)
+ return S_FALSE;
+ const Byte *p4 = p2 + offset;
+ if (x_type == INO_EXT_TYPE_NAME)
+ {
+ if (x_size < 2)
+ return S_FALSE;
+ inode.PrimaryName.SetFrom_CalcLen((const char *)p4, x_size);
+ PRF(printf(" PrimaryName = %s", inode.PrimaryName.Ptr()));
+ if (inode.PrimaryName.Len() != x_size - 1)
+ HeadersError = true;
+ // return S_FALSE;
+ }
+ else if (x_type == INO_EXT_TYPE_DSTREAM)
+ {
+ if (x_size != k_SizeOf_j_dstream)
+ return S_FALSE;
+ if (inode.dstream_defined)
+ return S_FALSE;
+ inode.dstream.Parse(p4);
+ inode.dstream_defined = true;
+ }
+ else
+ {
+ // UnsupportedFeature = true;
+ // return S_FALSE;
+ }
+ offset += x_size_ceil;
+ }
+ if (offset != extraSize)
+ return S_FALSE;
+ }
+
+ if (!vol.NodeIDs.IsEmpty())
+ if (id <= vol.NodeIDs.Back())
+ return S_FALSE;
+ vol.Nodes.Add(inode);
+ vol.NodeIDs.Add(id);
+ continue;
+ }
+
+ if (type == APFS_TYPE_XATTR)
+ {
+ PRF(printf(" XATTR"));
+
+ /*
+ struct j_xattr_key
+ {
+ j_key_t hdr;
+ uint16_t name_len;
+ uint8_t name[0];
+ }
+ */
+
+ UInt32 len;
+ unsigned nameOffset;
+ {
+ nameOffset = 8 + 2;
+ if (pair.Key.Size() < nameOffset + 1)
+ return S_FALSE;
+ len = Get16(p + 8);
+ }
+ if (nameOffset + len != pair.Key.Size())
+ return S_FALSE;
+
+ CAttr attr;
+ attr.Name.SetFrom_CalcLen((const char *)p + nameOffset, len);
+ if (attr.Name.Len() != len - 1)
+ return S_FALSE;
+
+ PRF(printf(" name=%s", attr.Name.Ptr()));
+
+ const unsigned k_SizeOf_j_xattr_val = 4;
+ if (pair.Val.Size() < k_SizeOf_j_xattr_val)
+ return S_FALSE;
+ /*
+ struct j_xattr_val
+ {
+ uint16_t flags;
+ uint16_t xdata_len;
+ uint8_t xdata[0];
+ }
+ */
+ attr.flags = Get16(pair.Val);
+ const UInt32 xdata_len = Get16(pair.Val + 2);
+
+ PRF(printf(" flags=%x xdata_len = %d",
+ (unsigned)attr.flags,
+ (unsigned)xdata_len));
+
+ const Byte *p4 = pair.Val + 4;
+
+ if (k_SizeOf_j_xattr_val + xdata_len != pair.Val.Size())
+ return S_FALSE;
+ if (attr.Is_EMBEDDED())
+ attr.Data.CopyFrom(p4, xdata_len);
+ else if (attr.Is_STREAM())
+ {
+ // why (attr.flags == 0x11) here? (0x11 is undocummented flag)
+ if (k_SizeOf_j_xattr_val + 8 + k_SizeOf_j_dstream != pair.Val.Size())
+ return S_FALSE;
+ attr.Id = Get64(p4);
+ attr.dstream.Parse(p4 + 8);
+ attr.dstream_defined = true;
+ PRF(printf(" streamID=%d", (unsigned)attr.Id));
+ }
+ else
+ {
+ // unknown attribute
+ // UnsupportedFeature = true;
+ // return S_FALSE;
+ }
+
+ if (vol.NodeIDs.IsEmpty() ||
+ vol.NodeIDs.Back() != id)
+ {
+ return S_FALSE;
+ // UnsupportedFeature = true;
+ // continue;
+ }
+ CNode &inode = vol.Nodes.Back();
+ if (attr.Name.IsEqualTo("com.apple.fs.symlink"))
+ {
+ inode.SymLinkIndex = inode.Attrs.Size();
+ if (attr.Is_dstream_OK_for_SymLink())
+ NeedReadSymLink = true;
+ }
+ else
+ vol.NumAltStreams++;
+ inode.Attrs.Add(attr);
+ continue;
+ }
+
+ if (type == APFS_TYPE_DSTREAM_ID)
+ {
+ PRF(printf(" DSTREAM_ID"));
+ if (pair.Key.Size() != 8)
+ return S_FALSE;
+ // j_dstream_id_val_t
+ if (pair.Val.Size() != 4)
+ return S_FALSE;
+ const UInt32 refcnt = Get32(pair.Val);
+
+ // The data stream record can be deleted when its reference count reaches zero.
+ PRF(printf(" refcnt = %8d", (unsigned)refcnt));
+
+ if (vol.NodeIDs.IsEmpty())
+ return S_FALSE;
+
+ if (vol.NodeIDs.Back() != id)
+ {
+ // is it possible ?
+ // continue;
+ return S_FALSE;
+ }
+
+ CNode &inode = vol.Nodes.Back();
+
+ if (inode.refcnt_defined)
+ return S_FALSE;
+
+ inode.refcnt = refcnt;
+ inode.refcnt_defined = true;
+ if (inode.refcnt != (UInt32)inode.nlink)
+ {
+ // is it possible ?
+ // return S_FALSE;
+ }
+ continue;
+ }
+
+ if (type == APFS_TYPE_FILE_EXTENT)
+ {
+ PRF(printf(" FILE_EXTENT"));
+ /*
+ struct j_file_extent_key
+ {
+ j_key_t hdr;
+ uint64_t logical_addr;
+ }
+ */
+ if (pair.Key.Size() != 16)
+ return S_FALSE;
+ // The offset within the file's data, in bytes, for the data stored in this extent
+ const UInt64 logical_addr = Get64(p + 8);
+
+ j_file_extent_val eval;
+ if (pair.Val.Size() != k_SizeOf_j_file_extent_val)
+ return S_FALSE;
+ eval.Parse(pair.Val);
+
+ if (logical_addr != 0)
+ {
+ PRF(printf(" logical_addr = %d", (unsigned)logical_addr));
+ }
+ PRF(printf(" len = %8d pos = %8d",
+ (unsigned)eval.len_and_flags,
+ (unsigned)eval.phys_block_num
+ ));
+
+ CExtent ext;
+ ext.logical_offset = logical_addr;
+ ext.len_and_flags = eval.len_and_flags;
+ ext.phys_block_num = eval.phys_block_num;
+
+ if (vol.NodeIDs.IsEmpty())
+ return S_FALSE;
+ if (vol.NodeIDs.Back() != id)
+ {
+ // extents for Attributs;
+ if (vol.SmallNodeIDs.IsEmpty() ||
+ vol.SmallNodeIDs.Back() != id)
+ {
+ vol.SmallNodeIDs.Add(id);
+ vol.SmallNodes.AddNew();
+ }
+ vol.SmallNodes.Back().Extents.Add(ext);
+ continue;
+ // return S_FALSE;
+ }
+
+ CNode &inode = vol.Nodes.Back();
+ inode.Extents.Add(ext);
+ continue;
+ }
+
+ if (type == APFS_TYPE_DIR_REC)
+ {
+ UInt32 len;
+ unsigned nameOffset;
+
+ if (isHashed)
+ {
+ /*
+ struct j_drec_hashed_key
+ {
+ j_key_t hdr;
+ UInt32 name_len_and_hash;
+ uint8_t name[0];
+ }
+ */
+ nameOffset = 8 + 4;
+ if (pair.Key.Size() < nameOffset + 1)
+ return S_FALSE;
+ const UInt32 name_len_and_hash = Get32(p + 8);
+ len = name_len_and_hash & J_DREC_LEN_MASK;
+ }
+ else
+ {
+ /*
+ struct j_drec_key
+ {
+ j_key_t hdr;
+ UInt16 name_len; // The length of the name, including the final null character
+ uint8_t name[0]; // The name, represented as a null-terminated UTF-8 string
+ }
+ */
+ nameOffset = 8 + 2;
+ if (pair.Key.Size() < nameOffset + 1)
+ return S_FALSE;
+ len = Get16(p + 8);
+ }
+ if (nameOffset + len != pair.Key.Size())
+ return S_FALSE;
+ CItem item;
+ item.ParentId = id;
+ item.Name.SetFrom_CalcLen((const char *)p + nameOffset, len);
+ if (item.Name.Len() != len - 1)
+ return S_FALSE;
+
+ if (pair.Val.Size() < k_SizeOf_j_drec_val)
+ return S_FALSE;
+
+ item.Val.Parse(pair.Val);
+
+ if (pair.Val.Size() > k_SizeOf_j_drec_val)
+ {
+ // fixme: parse extra fields;
+ // UnsupportedFeature = true;
+ // return S_FALSE;
+ }
+
+ vol.Items.Add(item);
+
+ /*
+ if (!vol.NodeIDs.IsEmpty() && vol.NodeIDs.Back() == id)
+ vol.Nodes.Back().NumItems++;
+ */
+ if (id == PRIV_DIR_INO_NUM)
+ vol.NumItems_In_PrivateDir++;
+
+ PRF(printf(" next=%6d flags=%2x %s",
+ (unsigned)item.Val.file_id,
+ (unsigned)item.Val.flags,
+ item.Name.Ptr()));
+ continue;
+ }
+
+ UnsupportedFeature = true;
+ // return S_FALSE;
+ }
+ ProgressVal_NumFilesTotal += vol.Items.Size();
+ }
+
+ if (NeedReadSymLink)
+ {
+ /* we read external streams for SymLinks to CAttr.Data
+ So we can get SymLink for GetProperty(kpidSymLink) later */
+ FOR_VECTOR (i, vol.Nodes)
+ {
+ CNode &node = vol.Nodes[i];
+ if (IsViNotDef(node.SymLinkIndex))
+ continue;
+ CAttr &attr = node.Attrs[(unsigned)node.SymLinkIndex];
+ // FOR_VECTOR (k, node.Attrs) { CAttr &attr = node.Attrs[(unsigned)k]; // for debug
+ if (attr.Data.Size() != 0
+ || !attr.Is_dstream_OK_for_SymLink())
+ continue;
+ const UInt32 size = (UInt32)attr.dstream.size;
+ const int idIndex = vol.SmallNodeIDs.FindInSorted(attr.Id);
+ if (idIndex == -1)
+ continue;
+ CMyComPtr<ISequentialInStream> inStream;
+ const HRESULT res = GetStream2(
+ OpenInStream,
+ &vol.SmallNodes[(unsigned)idIndex].Extents,
+ size, &inStream);
+ if (res == S_OK && inStream)
+ {
+ CByteBuffer buf2;
+ buf2.Alloc(size);
+ if (ReadStream_FAIL(inStream, buf2, size) == S_OK)
+ attr.Data = buf2;
+ }
+ }
+ }
+
+ const HRESULT res = vol.FillRefs();
+
+ if (vol.ThereAreErrors())
+ HeadersError = true;
+ if (vol.UnsupportedFeature)
+ UnsupportedFeature = true;
+ if (vol.NumAltStreams != 0)
+ ThereAreAltStreams = true;
+
+ return res;
+}
+
+
+
+HRESULT CVol::FillRefs()
+{
+ {
+ // we fill Refs[*]
+ // we
+ // and set Nodes[*].ItemIndex for Nodes that are dictories;
+ FOR_VECTOR (i, Items)
+ {
+ CItem &item = Items[i];
+ const UInt64 id = item.Val.file_id;
+ // if (item.Id == ROOT_DIR_PARENT) continue;
+ /* for two root folders items
+ we don't set Node.ItemIndex; */
+ // so nodes
+ if (id == ROOT_DIR_INO_NUM)
+ continue;
+ if (id == PRIV_DIR_INO_NUM)
+ if (NumItems_In_PrivateDir == 0) // if (inode.NumItems == 0)
+ continue;
+
+ CRef ref;
+ ref.ItemIndex = i;
+ // ref.NodeIndex = VI_MINUS1;
+ ref.ParentRefIndex = VI_MINUS1;
+ #ifdef APFS_SHOW_ALT_STREAMS
+ ref.AttrIndex = VI_MINUS1;
+ #endif
+ const int index = NodeIDs.FindInSorted(id);
+ // const int index = -1; // for debug
+ ref.NodeIndex = (unsigned)index;
+ item.RefIndex = Refs.Size();
+ Refs.Add(ref);
+
+ if (index == -1)
+ {
+ NodeNotFound = true;
+ continue;
+ // return S_FALSE;
+ }
+
+ // item.iNode_Index = index;
+ CNode &inode = Nodes[(unsigned)index];
+ if (!item.Val.IsFlags_Unknown()
+ && inode.Get_Type_From_mode() != item.Val.flags)
+ {
+ Refs.Back().NodeIndex = VI_MINUS1;
+ WrongInodeLink = true;
+ continue;
+ // return S_FALSE;
+ }
+
+ const bool isDir = inode.IsDir();
+ if (isDir)
+ {
+ if (IsViDef(inode.ItemIndex))
+ {
+ // hard links to dirs are not supported
+ Refs.Back().NodeIndex = VI_MINUS1;
+ WrongInodeLink = true;
+ continue;
+ }
+ inode.ItemIndex = i;
+ }
+ inode.NumCalcedLinks++;
+
+ #ifdef APFS_SHOW_ALT_STREAMS
+ if (!isDir)
+ {
+ // we use alt streams only for files
+ const unsigned numAttrs = inode.Attrs.Size();
+ if (numAttrs != 0)
+ {
+ ref.ParentRefIndex = item.RefIndex;
+ for (unsigned k = 0; k < numAttrs; k++)
+ {
+ if (k == inode.SymLinkIndex)
+ continue;
+ ref.AttrIndex = k;
+ Refs.Add(ref);
+ /*
+ const CAttr &attr = inode.Attrs[k];
+ if (attr.dstream_defined)
+ {
+ const int idIndex = SmallNodeIDs.FindInSorted(attr.Id);
+ if (idIndex != -1)
+ SmallNodes[(unsigned)idIndex].NumLinks++; // for debug
+ }
+ */
+ }
+ }
+ }
+ #endif
+ }
+ }
+
+
+ {
+ // fill ghost nodes
+ CRef ref;
+ ref.ItemIndex = VI_MINUS1;
+ ref.ParentRefIndex = VI_MINUS1;
+ #ifdef APFS_SHOW_ALT_STREAMS
+ ref.AttrIndex = VI_MINUS1;
+ #endif
+ FOR_VECTOR (i, Nodes)
+ {
+ if (Nodes[i].NumCalcedLinks != 0)
+ continue;
+ const UInt64 id = NodeIDs[i];
+ if (id == ROOT_DIR_INO_NUM ||
+ id == PRIV_DIR_INO_NUM)
+ continue;
+ ThereAreUnlinkedNodes = true;
+ ref.NodeIndex = i;
+ Refs.Add(ref);
+ }
+ }
+
+ /* if want to create Refs for ghost data streams,
+ we need additional CRef::SmallNodeIndex field */
+
+ {
+ /* all Nodes[*].ItemIndex were already filled for directory Nodes,
+ except of "root" and "private-dir" Nodes. */
+
+ // now we fill Items[*].ParentItemIndex and Refs[*].ParentRefIndex
+
+ UInt64 prev_ID = (UInt64)(Int64)-1;
+ unsigned prev_ParentItemIndex = VI_MINUS1;
+
+ FOR_VECTOR (i, Items)
+ {
+ CItem &item = Items[i];
+ const UInt64 id = item.ParentId; // it's id of parent NODE
+ if (id != prev_ID)
+ {
+ prev_ID = id;
+ prev_ParentItemIndex = VI_MINUS1;
+ const int index = NodeIDs.FindInSorted(id);
+ if (index == -1)
+ continue;
+ prev_ParentItemIndex = Nodes[(unsigned)index].ItemIndex;
+ }
+
+ if (IsViNotDef(prev_ParentItemIndex))
+ continue;
+ item.ParentItemIndex = prev_ParentItemIndex;
+ if (IsViNotDef(item.RefIndex))
+ {
+ // RefIndex is not set for 2 Items (root folders)
+ // but there is no node for them usually
+ continue;
+ }
+ CRef &ref = Refs[item.RefIndex];
+
+ /*
+ // it's optional check that parent_id is set correclty
+ if (IsViDef(ref.NodeIndex))
+ {
+ const CNode &node = Nodes[ref.NodeIndex];
+ if (node.IsDir() && node.parent_id != id)
+ return S_FALSE;
+ }
+ */
+
+ /*
+ if (id == ROOT_DIR_INO_NUM)
+ {
+ // ItemIndex in Node for ROOT_DIR_INO_NUM was not set bofere
+ // probably unused now.
+ ref.ParentRefIndex = VI_MINUS1;
+ }
+ else
+ */
+ ref.ParentRefIndex = Items[prev_ParentItemIndex].RefIndex;
+ }
+ }
+
+ {
+ // check for loops
+ const unsigned numItems = Items.Size();
+ if (numItems + 1 == 0)
+ return S_FALSE;
+ CUIntArr arr;
+ arr.Alloc(numItems);
+ {
+ for (unsigned i = 0; i < numItems; i++)
+ arr[i] = 0;
+ }
+ for (unsigned i = 0; i < numItems;)
+ {
+ unsigned k = i++;
+ for (;;)
+ {
+ const unsigned a = arr[k];
+ if (a != 0)
+ {
+ if (a == i)
+ return S_FALSE;
+ break;
+ }
+ arr[k] = i;
+ k = Items[k].ParentItemIndex;
+ if (IsViNotDef(k))
+ break;
+ }
+ }
+ }
+
+ return S_OK;
+}
+
+
+
+class CHandler:
+ public IInArchive,
+ public IArchiveGetRawProps,
+ public IInArchiveGetStream,
+ public CMyUnknownImp,
+ public CDatabase
+{
+ CMyComPtr<IInStream> _stream;
+public:
+ MY_UNKNOWN_IMP3(IInArchive, IArchiveGetRawProps, IInArchiveGetStream)
+ INTERFACE_IInArchive(;)
+ INTERFACE_IArchiveGetRawProps(;)
+ STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
+};
+
+
+STDMETHODIMP CHandler::Open(IInStream *inStream,
+ const UInt64 * /* maxCheckStartPosition */,
+ IArchiveOpenCallback *callback)
+{
+ COM_TRY_BEGIN
+ Close();
+ OpenInStream = inStream;
+ OpenCallback = callback;
+ RINOK(Open2());
+ _stream = inStream;
+ return S_OK;
+ COM_TRY_END
+}
+
+
+STDMETHODIMP CHandler::Close()
+{
+ _stream.Release();
+ Clear();
+ return S_OK;
+}
+
+
+enum
+{
+ kpidBytesWritten = kpidUserDefined,
+ kpidBytesRead,
+ kpidPrimeName,
+ kpidParentINode,
+ kpidAddTime,
+ kpidGeneration,
+ kpidBsdFlags
+};
+
+static const CStatProp kProps[] =
+{
+ { NULL, kpidPath, VT_BSTR },
+ { NULL, kpidSize, VT_UI8 },
+ { NULL, kpidPackSize, VT_UI8 },
+ { NULL, kpidPosixAttrib, VT_UI4 },
+ { NULL, kpidMTime, VT_FILETIME },
+ { NULL, kpidCTime, VT_FILETIME },
+ { NULL, kpidATime, VT_FILETIME },
+ { NULL, kpidChangeTime, VT_FILETIME },
+ { "Added Time", kpidAddTime, VT_FILETIME },
+ { NULL, kpidINode, VT_UI8 },
+ { NULL, kpidLinks, VT_UI4 },
+ { NULL, kpidSymLink, VT_BSTR },
+ { NULL, kpidUserId, VT_UI4 },
+ { NULL, kpidGroupId, VT_UI4 },
+ #ifdef APFS_SHOW_ALT_STREAMS
+ { NULL, kpidIsAltStream, VT_BOOL },
+ #endif
+ { "Parent iNode", kpidParentINode, VT_UI8 },
+ { "Primary Name", kpidPrimeName, VT_BSTR },
+ { "Generation", kpidGeneration, VT_UI4 },
+ { "Written Size", kpidBytesWritten, VT_UI8 },
+ { "Read Size", kpidBytesRead, VT_UI8 },
+ { "BSD Flags", kpidBsdFlags, VT_UI4 }
+};
+
+
+static const Byte kArcProps[] =
+{
+ kpidName,
+ kpidId,
+ kpidClusterSize,
+ kpidCTime,
+ kpidMTime,
+ kpidComment
+};
+
+IMP_IInArchive_Props_WITH_NAME
+IMP_IInArchive_ArcProps
+
+
+static void ApfsTimeToProp(UInt64 hfsTime, NWindows::NCOM::CPropVariant &prop)
+{
+ if (hfsTime == 0)
+ return;
+ FILETIME ft;
+ UInt32 ns100;
+ ApfsTimeToFileTime(hfsTime, ft, ns100);
+ prop.SetAsTimeFrom_FT_Prec_Ns100(ft, k_PropVar_TimePrec_1ns, ns100);
+}
+
+
+STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NWindows::NCOM::CPropVariant prop;
+ const CApfs *apfs = NULL;
+ if (Vols.Size() == 1)
+ apfs = &Vols[0].apfs;
+ switch (propID)
+ {
+ case kpidPhySize:
+ prop = (UInt64)sb.block_count << sb.block_size_Log;
+ break;
+ case kpidClusterSize: prop = (UInt32)(sb.block_size); break;
+ case kpidMTime:
+ if (apfs)
+ ApfsTimeToProp(apfs->modified_by[0].timestamp, prop);
+ break;
+ case kpidCTime:
+ if (apfs)
+ ApfsTimeToProp(apfs->formatted_by.timestamp, prop);
+ break;
+ case kpidIsTree: prop = true; break;
+ case kpidErrorFlags:
+ {
+ UInt32 flags = 0;
+ if (HeadersError) flags |= kpv_ErrorFlags_HeadersError;
+ if (flags != 0)
+ prop = flags;
+ break;
+ }
+ case kpidWarningFlags:
+ {
+ UInt32 flags = 0;
+ if (UnsupportedFeature) flags |= kpv_ErrorFlags_UnsupportedFeature;
+ if (flags != 0)
+ prop = flags;
+ break;
+ }
+
+ case kpidName:
+ {
+ if (apfs)
+ {
+ UString s;
+ AddVolInternalName_toString(s, *apfs);
+ s += ".apfs";
+ prop = s;
+ }
+ break;
+ }
+
+ case kpidId:
+ {
+ char s[32 + 4];
+ sb.uuid.SetHex_To_str(s);
+ prop = s;
+ break;
+ }
+
+ case kpidComment:
+ {
+ UString s;
+ {
+ AddComment_UInt64(s, "block_size", sb.block_size);
+
+ FOR_VECTOR (i, Vols)
+ {
+ if (Vols.Size() > 1)
+ {
+ if (i != 0)
+ {
+ s += "----";
+ s.Add_LF();
+ }
+ AddComment_UInt64(s, "Volume", i + 1);
+ }
+ Vols[i].AddComment(s);
+ }
+ }
+ prop = s;
+ break;
+ }
+
+ #ifdef APFS_SHOW_ALT_STREAMS
+ case kpidIsAltStream:
+ prop = ThereAreAltStreams;
+ // prop = false; // for debug
+ break;
+ #endif
+ }
+ prop.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+
+STDMETHODIMP CHandler::GetNumRawProps(UInt32 *numProps)
+{
+ *numProps = 0;
+ return S_OK;
+}
+
+
+STDMETHODIMP CHandler::GetRawPropInfo(UInt32 /* index */, BSTR *name, PROPID *propID)
+{
+ *name = NULL;
+ *propID = 0;
+ return S_OK;
+}
+
+
+STDMETHODIMP CHandler::GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType)
+{
+ *parentType = NParentType::kDir;
+
+ const CRef2 &ref2 = Refs2[index];
+ const CVol &vol = Vols[ref2.VolIndex];
+ UInt32 parentIndex = (UInt32)(Int32)-1;
+ *parentType = NParentType::kDir;
+
+ if (IsViDef(ref2.RefIndex))
+ {
+ const CRef &ref = vol.Refs[ref2.RefIndex];
+ #ifdef APFS_SHOW_ALT_STREAMS
+ if (ref.IsAltStream())
+ *parentType = NParentType::kAltStream;
+ #endif
+ if (IsViDef(ref.ParentRefIndex))
+ parentIndex = (UInt32)(ref.ParentRefIndex + vol.StartRef2Index);
+ else if (index != vol.RootRef2Index && IsViDef(vol.RootRef2Index))
+ parentIndex = (UInt32)vol.RootRef2Index;
+ }
+
+ *parent = parentIndex;
+ return S_OK;
+}
+
+
+STDMETHODIMP CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)
+{
+ *data = NULL;
+ *dataSize = 0;
+ *propType = 0;
+ UNUSED_VAR(index);
+ UNUSED_VAR(propID);
+ return S_OK;
+}
+
+
+static void Utf8Name_to_InterName(const AString &src, UString &dest)
+{
+ ConvertUTF8ToUnicode(src, dest);
+ NItemName::NormalizeSlashes_in_FileName_for_OsPath(dest);
+}
+
+
+static void AddNodeName(UString &s, const CNode &inode, UInt64 id)
+{
+ s += "node";
+ s.Add_UInt64(id);
+ if (!inode.PrimaryName.IsEmpty())
+ {
+ s += '.';
+ UString s2;
+ Utf8Name_to_InterName(inode.PrimaryName, s2);
+ s += s2;
+ }
+}
+
+
+void CDatabase::GetItemPath(unsigned index, const CNode *inode, NWindows::NCOM::CPropVariant &path) const
+{
+ const unsigned kNumLevelsMax = (1 << 10);
+ const unsigned kLenMax = (1 << 12);
+ UString s;
+ const CRef2 &ref2 = Refs2[index];
+ const CVol &vol = Vols[ref2.VolIndex];
+
+ if (IsViDef(ref2.RefIndex))
+ {
+ const CRef &ref = vol.Refs[ref2.RefIndex];
+ unsigned cur = ref.ItemIndex;
+ if (IsViNotDef(cur))
+ {
+ if (inode)
+ AddNodeName(s, *inode, vol.NodeIDs[ref.NodeIndex]);
+ }
+ else
+ {
+ for (unsigned i = 0;; i++)
+ {
+ if (i >= kNumLevelsMax || s.Len() > kLenMax)
+ {
+ s.Insert(0, UString("[LONG_PATH]"));
+ break;
+ }
+ const CItem &item = vol.Items[(unsigned)cur];
+ UString s2;
+ Utf8Name_to_InterName(item.Name, s2);
+ // s2 += "a\\b"; // for debug
+ s.Insert(0, s2);
+ cur = item.ParentItemIndex;
+ if (IsViNotDef(cur))
+ break;
+ // ParentItemIndex was not set for sch items
+ // if (item.ParentId == ROOT_DIR_INO_NUM) break;
+ s.InsertAtFront(WCHAR_PATH_SEPARATOR);
+ }
+ }
+
+ #ifdef APFS_SHOW_ALT_STREAMS
+ if (IsViDef(ref.AttrIndex) && inode)
+ {
+ s += ':';
+ UString s2;
+ Utf8Name_to_InterName(inode->Attrs[(unsigned)ref.AttrIndex].Name, s2);
+ // s2 += "a\\b"; // for debug
+ s += s2;
+ }
+ #endif
+ }
+
+ if (!vol.RootName.IsEmpty())
+ {
+ if (IsViDef(ref2.RefIndex))
+ s.InsertAtFront(WCHAR_PATH_SEPARATOR);
+ s.Insert(0, vol.RootName);
+ }
+
+ path = s;
+}
+
+
+
+STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NWindows::NCOM::CPropVariant prop;
+
+ const CRef2 &ref2 = Refs2[index];
+ const CVol &vol = Vols[ref2.VolIndex];
+
+ if (IsViNotDef(ref2.RefIndex))
+ {
+ switch (propID)
+ {
+ case kpidName:
+ case kpidPath:
+ GetItemPath(index, NULL, prop);
+ break;
+ case kpidIsDir:
+ prop = true;
+ break;
+ }
+ prop.Detach(value);
+ return S_OK;
+ }
+
+ const CRef &ref = vol.Refs[ref2.RefIndex];
+
+ const CItem *item = NULL;
+ if (IsViDef(ref.ItemIndex))
+ item = &vol.Items[ref.ItemIndex];
+
+ const CNode *inode = NULL;
+ if (IsViDef(ref.NodeIndex))
+ inode = &vol.Nodes[ref.NodeIndex];
+
+ switch (propID)
+ {
+ case kpidPath:
+ GetItemPath(index, inode, prop);
+ break;
+ case kpidPrimeName:
+ {
+ if (inode
+ #ifdef APFS_SHOW_ALT_STREAMS
+ && !ref.IsAltStream()
+ #endif
+ && !inode->PrimaryName.IsEmpty())
+ {
+ UString s;
+ ConvertUTF8ToUnicode(inode->PrimaryName, s);
+ /*
+ // for debug:
+ if (inode.PrimaryName != item.Name) throw 123456;
+ */
+ prop = s;
+ }
+ break;
+ }
+
+ case kpidName:
+ {
+ UString s;
+ #ifdef APFS_SHOW_ALT_STREAMS
+ if (ref.IsAltStream())
+ {
+ // if (inode)
+ {
+ const CAttr &attr = inode->Attrs[(unsigned)ref.AttrIndex];
+ ConvertUTF8ToUnicode(attr.Name, s);
+ }
+ }
+ else
+ #endif
+ {
+ if (item)
+ ConvertUTF8ToUnicode(item->Name, s);
+ else if (inode)
+ AddNodeName(s, *inode, vol.NodeIDs[ref.NodeIndex]);
+ else
+ break;
+ }
+ // s += "s/1bs\\2"; // for debug:
+ prop = s;
+ break;
+ }
+
+ case kpidSymLink:
+ if (inode)
+ {
+ if (inode->IsSymLink() && IsViDef(inode->SymLinkIndex))
+ {
+ const CByteBuffer &buf = inode->Attrs[(unsigned)inode->SymLinkIndex].Data;
+ if (buf.Size() != 0)
+ {
+ AString s;
+ s.SetFrom_CalcLen((const char *)(const Byte *)buf, (unsigned)buf.Size());
+ if (s.Len() == buf.Size() - 1)
+ {
+ UString u;
+ ConvertUTF8ToUnicode(s, u);
+ prop = u;
+ }
+ }
+ }
+ }
+ break;
+
+ case kpidSize:
+ if (inode)
+ {
+ UInt64 size;
+ if (inode->GetSize(ref.GetAttrIndex(), size))
+ prop = size;
+ }
+ break;
+
+ case kpidPackSize:
+ if (inode)
+ {
+ UInt64 size;
+ if (inode->GetPackSize(ref.GetAttrIndex(), size))
+ prop = size;
+ }
+ break;
+
+ case kpidIsDir:
+ {
+ bool isDir = false;
+ if (inode)
+ isDir = inode->IsDir();
+ else if (item)
+ isDir = item->Val.IsFlags_Dir();
+ prop = isDir;
+ break;
+ }
+
+ case kpidPosixAttrib:
+ {
+ if (inode)
+ {
+ UInt32 mode = inode->mode;
+ #ifdef APFS_SHOW_ALT_STREAMS
+ if (ref.IsAltStream())
+ {
+ mode &= 0666; // we disable execution
+ mode |= MY_LIN_S_IFREG;
+ }
+ #endif
+ prop = (UInt32)mode;
+ }
+ else if (item && !item->Val.IsFlags_Unknown())
+ prop = (UInt32)(item->Val.flags << 12);
+ break;
+ }
+
+ case kpidCTime: if (inode) ApfsTimeToProp(inode->create_time, prop); break;
+ case kpidMTime: if (inode) ApfsTimeToProp(inode->mod_time, prop); break;
+ case kpidATime: if (inode) ApfsTimeToProp(inode->access_time, prop); break;
+ case kpidChangeTime: if (inode) ApfsTimeToProp(inode->change_time, prop); break;
+ case kpidAddTime: if (item) ApfsTimeToProp(item->Val.date_added, prop); break;
+
+ case kpidBytesWritten:
+ #ifdef APFS_SHOW_ALT_STREAMS
+ if (!ref.IsAltStream())
+ #endif
+ if (inode && inode->dstream_defined)
+ prop = inode->dstream.total_bytes_written;
+ break;
+ case kpidBytesRead:
+ #ifdef APFS_SHOW_ALT_STREAMS
+ if (!ref.IsAltStream())
+ #endif
+ if (inode && inode->dstream_defined)
+ prop = inode->dstream.total_bytes_read;
+ break;
+
+ #ifdef APFS_SHOW_ALT_STREAMS
+ case kpidIsAltStream:
+ prop = ref.IsAltStream();
+ break;
+ #endif
+
+ case kpidCharacts:
+ if (inode)
+ {
+ FLAGS_TO_PROP(g_INODE_Flags, (UInt32)inode->internal_flags, prop);
+ }
+ break;
+
+ case kpidBsdFlags:
+ if (inode)
+ {
+ FLAGS_TO_PROP(g_INODE_BSD_Flags, inode->bsd_flags, prop);
+ }
+ break;
+
+ case kpidGeneration:
+ if (inode)
+ prop = inode->write_generation_counter;
+ break;
+
+ case kpidUserId:
+ if (inode)
+ prop = (UInt32)inode->owner;
+ break;
+
+ case kpidGroupId:
+ if (inode)
+ prop = (UInt32)inode->group;
+ break;
+
+ case kpidLinks:
+ if (inode && !inode->IsDir())
+ prop = (UInt32)inode->nlink;
+ break;
+
+ case kpidINode:
+ #ifdef APFS_SHOW_ALT_STREAMS
+ // here we can disable iNode for alt stream.
+ // if (!ref.IsAltStream())
+ #endif
+ if (IsViDef(ref.NodeIndex))
+ prop = (UInt32)vol.NodeIDs[ref.NodeIndex];
+ break;
+
+ case kpidParentINode:
+ if (inode)
+ prop = (UInt32)inode->parent_id;
+ break;
+ }
+ prop.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+
+UInt64 CDatabase::GetSize(const UInt32 index) const
+{
+ const CRef2 &ref2 = Refs2[index];
+ const CVol &vol = Vols[ref2.VolIndex];
+ if (IsViNotDef(ref2.RefIndex))
+ return 0;
+ const CRef &ref = vol.Refs[ref2.RefIndex];
+ if (IsViNotDef(ref.NodeIndex))
+ return 0;
+ const CNode &inode = vol.Nodes[ref.NodeIndex];
+ UInt64 size;
+ if (inode.GetSize(ref.GetAttrIndex(), size))
+ return size;
+ return 0;
+}
+
+
+STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
+ Int32 testMode, IArchiveExtractCallback *extractCallback)
+{
+ COM_TRY_BEGIN
+ const bool allFilesMode = (numItems == (UInt32)(Int32)-1);
+ if (allFilesMode)
+ numItems = Refs2.Size();
+ if (numItems == 0)
+ return S_OK;
+ UInt32 i;
+
+ {
+ UInt64 totalSize = 0;
+ for (i = 0; i < numItems; i++)
+ {
+ const UInt32 index = allFilesMode ? i : indices[i];
+ totalSize += GetSize(index);
+ }
+ RINOK(extractCallback->SetTotal(totalSize));
+ }
+
+ UInt64 currentTotalSize = 0, currentItemSize = 0;
+
+ CLocalProgress *lps = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> progress = lps;
+ lps->Init(extractCallback, false);
+
+ NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
+ CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
+
+ for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize)
+ {
+ lps->InSize = currentTotalSize;
+ lps->OutSize = currentTotalSize;
+ RINOK(lps->SetCur());
+
+ const UInt32 index = allFilesMode ? i : indices[i];
+ const CRef2 &ref2 = Refs2[index];
+ const CVol &vol = Vols[ref2.VolIndex];
+
+ currentItemSize = GetSize(index);
+
+ CMyComPtr<ISequentialOutStream> realOutStream;
+
+ const Int32 askMode = testMode ?
+ NExtract::NAskMode::kTest :
+ NExtract::NAskMode::kExtract;
+ RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
+
+ if (IsViNotDef(ref2.RefIndex))
+ {
+ RINOK(extractCallback->PrepareOperation(askMode));
+ RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
+ continue;
+ }
+
+ const CRef &ref = vol.Refs[ref2.RefIndex];
+ bool isDir = false;
+ if (IsViDef(ref.NodeIndex))
+ isDir = vol.Nodes[ref.NodeIndex].IsDir();
+ else if (IsViDef(ref.ItemIndex))
+ isDir =
+ #ifdef APFS_SHOW_ALT_STREAMS
+ !ref.IsAltStream() &&
+ #endif
+ vol.Items[ref.ItemIndex].Val.IsFlags_Dir();
+
+ if (isDir)
+ {
+ RINOK(extractCallback->PrepareOperation(askMode));
+ RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
+ continue;
+ }
+ if (!testMode && !realOutStream)
+ continue;
+ RINOK(extractCallback->PrepareOperation(askMode));
+ int opRes = NExtract::NOperationResult::kDataError;
+
+ CMyComPtr<ISequentialInStream> inStream;
+ if (GetStream(index, &inStream) == S_OK && inStream)
+ {
+ RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
+ opRes = NExtract::NOperationResult::kDataError;
+ if (copyCoderSpec->TotalSize == currentItemSize)
+ opRes = NExtract::NOperationResult::kOK;
+ else if (copyCoderSpec->TotalSize < currentItemSize)
+ opRes = NExtract::NOperationResult::kUnexpectedEnd;
+ }
+
+ realOutStream.Release();
+ RINOK(extractCallback->SetOperationResult(opRes));
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+
+STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
+{
+ *numItems = Refs2.Size();
+ return S_OK;
+}
+
+
+STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
+{
+ *stream = NULL;
+
+ const CRef2 &ref2 = Refs2[index];
+ const CVol &vol = Vols[ref2.VolIndex];
+ if (IsViNotDef(ref2.RefIndex))
+ return S_FALSE;
+
+ const CRef &ref = vol.Refs[ref2.RefIndex];
+ if (IsViNotDef(ref.NodeIndex))
+ return S_FALSE;
+ const CNode &inode = vol.Nodes[ref.NodeIndex];
+
+ const CRecordVector<CExtent> *extents;
+ UInt64 rem = 0;
+
+ unsigned attrIndex = ref.GetAttrIndex();
+
+ if (IsViNotDef(attrIndex)
+ && !inode.dstream_defined
+ && inode.IsSymLink())
+ {
+ attrIndex = inode.SymLinkIndex;
+ if (IsViNotDef(attrIndex))
+ return S_FALSE;
+ }
+
+ if (IsViDef(attrIndex))
+ {
+ const CAttr &attr = inode.Attrs[(unsigned)attrIndex];
+ if (!attr.dstream_defined)
+ {
+ CBufInStream *streamSpec = new CBufInStream;
+ CMyComPtr<ISequentialInStream> streamTemp = streamSpec;
+ streamSpec->Init(attr.Data, attr.Data.Size(), (IInArchive *)this);
+ *stream = streamTemp.Detach();
+ return S_OK;
+ }
+ const int idIndex = vol.SmallNodeIDs.FindInSorted(attr.Id);
+ if (idIndex == -1)
+ return S_FALSE;
+ extents = &vol.SmallNodes[(unsigned)idIndex].Extents;
+ rem = attr.dstream.size;
+ }
+ else
+ {
+ if (IsViDef(ref.ItemIndex))
+ if (vol.Items[ref.ItemIndex].Val.IsFlags_Dir())
+ return S_FALSE;
+ if (inode.IsDir())
+ return S_FALSE;
+ if (inode.dstream_defined)
+ rem = inode.dstream.size;
+ extents = &inode.Extents;
+ }
+ return GetStream2(_stream, extents, rem, stream);
+}
+
+
+
+HRESULT CDatabase::GetStream2(
+ IInStream *apfsInStream,
+ const CRecordVector<CExtent> *extents, UInt64 rem,
+ ISequentialInStream **stream)
+{
+ CExtentsStream *extentStreamSpec = new CExtentsStream();
+ CMyComPtr<ISequentialInStream> extentStream = extentStreamSpec;
+
+ UInt64 virt = 0;
+ FOR_VECTOR (i, *extents)
+ {
+ const CExtent &e = (*extents)[i];
+ if (virt != e.logical_offset)
+ return S_FALSE;
+ const UInt64 len = EXTENT_GET_LEN(e.len_and_flags);
+ if (len == 0)
+ {
+ return S_FALSE;
+ // continue;
+ }
+ if (rem == 0)
+ return S_FALSE;
+ UInt64 cur = len;
+ if (cur > rem)
+ cur = rem;
+ CSeekExtent se;
+ se.Phy = (UInt64)e.phys_block_num << sb.block_size_Log;
+ se.Virt = virt;
+ virt += cur;
+ rem -= cur;
+ extentStreamSpec->Extents.Add(se);
+ if (rem == 0)
+ if (i != extents->Size() - 1)
+ return S_FALSE;
+ }
+
+ if (rem != 0)
+ return S_FALSE;
+
+ CSeekExtent se;
+ se.Phy = 0;
+ se.Virt = virt;
+ extentStreamSpec->Extents.Add(se);
+ extentStreamSpec->Stream = apfsInStream;
+ extentStreamSpec->Init();
+ *stream = extentStream.Detach();
+ return S_OK;
+}
+
+
+REGISTER_ARC_I(
+ "APFS", "apfs img", NULL, 0xc3,
+ k_Signature,
+ k_SignatureOffset,
+ 0,
+ IsArc_APFS)
+
+}}
diff --git a/CPP/7zip/Archive/ApmHandler.cpp b/CPP/7zip/Archive/ApmHandler.cpp
index 73e5fcb6..73e5fcb6 100644..100755
--- a/CPP/7zip/Archive/ApmHandler.cpp
+++ b/CPP/7zip/Archive/ApmHandler.cpp
diff --git a/CPP/7zip/Archive/ArHandler.cpp b/CPP/7zip/Archive/ArHandler.cpp
index 0bea8b4e..6cd72bb3 100644..100755
--- a/CPP/7zip/Archive/ArHandler.cpp
+++ b/CPP/7zip/Archive/ArHandler.cpp
@@ -322,8 +322,8 @@ static const Byte kProps[] =
kpidSize,
kpidMTime,
kpidPosixAttrib,
- kpidUser,
- kpidGroup
+ kpidUserId,
+ kpidGroupId
};
IMP_IInArchive_Props
@@ -734,15 +734,11 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidMTime:
{
if (item.MTime != 0)
- {
- FILETIME fileTime;
- NTime::UnixTimeToFileTime(item.MTime, fileTime);
- prop = fileTime;
- }
+ PropVariant_SetFrom_UnixTime(prop, item.MTime);
break;
}
- case kpidUser: if (item.User != 0) prop = item.User; break;
- case kpidGroup: if (item.Group != 0) prop = item.Group; break;
+ case kpidUserId: if (item.User != 0) prop = item.User; break;
+ case kpidGroupId: if (item.Group != 0) prop = item.Group; break;
case kpidPosixAttrib:
if (item.TextFileIndex < 0)
prop = item.Mode;
diff --git a/CPP/7zip/Archive/Archive.def b/CPP/7zip/Archive/Archive.def
index 145516d7..145516d7 100644..100755
--- a/CPP/7zip/Archive/Archive.def
+++ b/CPP/7zip/Archive/Archive.def
diff --git a/CPP/7zip/Archive/Archive2.def b/CPP/7zip/Archive/Archive2.def
index c7582742..c7582742 100644..100755
--- a/CPP/7zip/Archive/Archive2.def
+++ b/CPP/7zip/Archive/Archive2.def
diff --git a/CPP/7zip/Archive/ArchiveExports.cpp b/CPP/7zip/Archive/ArchiveExports.cpp
index 6549b3d2..8a441bc2 100644..100755
--- a/CPP/7zip/Archive/ArchiveExports.cpp
+++ b/CPP/7zip/Archive/ArchiveExports.cpp
@@ -115,6 +115,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;
diff --git a/CPP/7zip/Archive/ArjHandler.cpp b/CPP/7zip/Archive/ArjHandler.cpp
index 0e353dca..125b9c20 100644..100755
--- a/CPP/7zip/Archive/ArjHandler.cpp
+++ b/CPP/7zip/Archive/ArjHandler.cpp
@@ -682,15 +682,7 @@ static void SetTime(UInt32 dosTime, NCOM::CPropVariant &prop)
{
if (dosTime == 0)
return;
- FILETIME localFileTime, utc;
- if (NTime::DosTimeToFileTime(dosTime, localFileTime))
- {
- if (!LocalFileTimeToFileTime(&localFileTime, &utc))
- utc.dwHighDateTime = utc.dwLowDateTime = 0;
- }
- else
- utc.dwHighDateTime = utc.dwLowDateTime = 0;
- prop = utc;
+ PropVariant_SetFrom_DosTime(prop, dosTime);
}
static void SetHostOS(Byte hostOS, NCOM::CPropVariant &prop)
diff --git a/CPP/7zip/Archive/Base64Handler.cpp b/CPP/7zip/Archive/Base64Handler.cpp
index 63b4552e..63b4552e 100644..100755
--- a/CPP/7zip/Archive/Base64Handler.cpp
+++ b/CPP/7zip/Archive/Base64Handler.cpp
diff --git a/CPP/7zip/Archive/Bz2Handler.cpp b/CPP/7zip/Archive/Bz2Handler.cpp
index b0c2f750..c89a53c5 100644..100755
--- a/CPP/7zip/Archive/Bz2Handler.cpp
+++ b/CPP/7zip/Archive/Bz2Handler.cpp
@@ -305,29 +305,91 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
}
+/*
+static HRESULT ReportItemProp(IArchiveUpdateCallbackArcProp *reportArcProp, PROPID propID, const PROPVARIANT *value)
+{
+ return reportArcProp->ReportProp(NEventIndexType::kOutArcIndex, 0, propID, value);
+}
+
+static HRESULT ReportArcProp(IArchiveUpdateCallbackArcProp *reportArcProp, PROPID propID, const PROPVARIANT *value)
+{
+ return reportArcProp->ReportProp(NEventIndexType::kArcProp, 0, propID, value);
+}
+
+static HRESULT ReportArcProps(IArchiveUpdateCallbackArcProp *reportArcProp,
+ const UInt64 *unpackSize,
+ const UInt64 *numBlocks)
+{
+ NCOM::CPropVariant sizeProp;
+ if (unpackSize)
+ {
+ sizeProp = *unpackSize;
+ RINOK(ReportItemProp(reportArcProp, kpidSize, &sizeProp));
+ RINOK(reportArcProp->ReportFinished(NEventIndexType::kOutArcIndex, 0, NArchive::NUpdate::NOperationResult::kOK));
+ }
+
+ if (unpackSize)
+ {
+ RINOK(ReportArcProp(reportArcProp, kpidSize, &sizeProp));
+ }
+ if (numBlocks)
+ {
+ NCOM::CPropVariant prop;
+ prop = *numBlocks;
+ RINOK(ReportArcProp(reportArcProp, kpidNumBlocks, &prop));
+ }
+ return S_OK;
+}
+*/
static HRESULT UpdateArchive(
UInt64 unpackSize,
ISequentialOutStream *outStream,
const CProps &props,
- IArchiveUpdateCallback *updateCallback)
+ IArchiveUpdateCallback *updateCallback
+ // , ArchiveUpdateCallbackArcProp *reportArcProp
+ )
{
- RINOK(updateCallback->SetTotal(unpackSize));
- CMyComPtr<ISequentialInStream> fileInStream;
- RINOK(updateCallback->GetStream(0, &fileInStream));
- CLocalProgress *localProgressSpec = new CLocalProgress;
- CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec;
- localProgressSpec->Init(updateCallback, true);
- NCompress::NBZip2::CEncoder *encoderSpec = new NCompress::NBZip2::CEncoder;
- CMyComPtr<ICompressCoder> encoder = encoderSpec;
- RINOK(props.SetCoderProps(encoderSpec, NULL));
- RINOK(encoder->Code(fileInStream, outStream, NULL, NULL, localProgress));
+ {
+ 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)
+ unpackSize = size;
+ }
+ }
+ RINOK(updateCallback->SetTotal(unpackSize));
+ CLocalProgress *localProgressSpec = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec;
+ localProgressSpec->Init(updateCallback, true);
+ {
+ NCompress::NBZip2::CEncoder *encoderSpec = new NCompress::NBZip2::CEncoder;
+ CMyComPtr<ICompressCoder> encoder = encoderSpec;
+ RINOK(props.SetCoderProps(encoderSpec, NULL));
+ RINOK(encoder->Code(fileInStream, outStream, NULL, NULL, localProgress));
+ /*
+ if (reportArcProp)
+ {
+ unpackSize = encoderSpec->GetInProcessedSize();
+ RINOK(ReportArcProps(reportArcProp, &unpackSize, &encoderSpec->NumBlocks));
+ }
+ */
+ }
+ }
return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK);
}
-STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
+STDMETHODIMP CHandler::GetFileTimeType(UInt32 *timeType)
{
- *type = NFileTimeType::kUnix;
+ *timeType = GET_FileTimeType_NotDefined_for_GetFileTimeType;
+ // *timeType = NFileTimeType::kUnix;
return S_OK;
}
@@ -345,6 +407,11 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
return E_FAIL;
RINOK(updateCallback->GetUpdateItemInfo(0, &newData, &newProps, &indexInArchive));
+ /*
+ CMyComPtr<IArchiveUpdateCallbackArcProp> reportArcProp;
+ updateCallback->QueryInterface(IID_IArchiveUpdateCallbackArcProp, (void **)&reportArcProp);
+ */
+
if (IntToBool(newProps))
{
{
@@ -396,6 +463,8 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
return NCompress::CopyStream(_stream, outStream, progress);
+ // return ReportArcProps(reportArcProp, NULL, NULL);
+
COM_TRY_END
}
@@ -410,7 +479,8 @@ REGISTER_ARC_IO(
"bzip2", "bz2 bzip2 tbz2 tbz", "* * .tar .tar", 2,
k_Signature,
0,
- NArcInfoFlags::kKeepName,
- IsArc_BZip2)
+ NArcInfoFlags::kKeepName
+ , 0
+ , IsArc_BZip2)
}}
diff --git a/CPP/7zip/Archive/Cab/CabBlockInStream.cpp b/CPP/7zip/Archive/Cab/CabBlockInStream.cpp
index c193434f..c193434f 100644..100755
--- a/CPP/7zip/Archive/Cab/CabBlockInStream.cpp
+++ b/CPP/7zip/Archive/Cab/CabBlockInStream.cpp
diff --git a/CPP/7zip/Archive/Cab/CabBlockInStream.h b/CPP/7zip/Archive/Cab/CabBlockInStream.h
index af89abb6..af89abb6 100644..100755
--- a/CPP/7zip/Archive/Cab/CabBlockInStream.h
+++ b/CPP/7zip/Archive/Cab/CabBlockInStream.h
diff --git a/CPP/7zip/Archive/Cab/CabHandler.cpp b/CPP/7zip/Archive/Cab/CabHandler.cpp
index fafd7aa0..804c921a 100644..100755
--- a/CPP/7zip/Archive/Cab/CabHandler.cpp
+++ b/CPP/7zip/Archive/Cab/CabHandler.cpp
@@ -295,15 +295,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidMTime:
{
- FILETIME localFileTime, utcFileTime;
- if (NTime::DosTimeToFileTime(item.Time, localFileTime))
- {
- if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime))
- utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
- }
- else
- utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
- prop = utcFileTime;
+ PropVariant_SetFrom_DosTime(prop, item.Time);
break;
}
diff --git a/CPP/7zip/Archive/Cab/CabHandler.h b/CPP/7zip/Archive/Cab/CabHandler.h
index 6f44b875..6f44b875 100644..100755
--- a/CPP/7zip/Archive/Cab/CabHandler.h
+++ b/CPP/7zip/Archive/Cab/CabHandler.h
diff --git a/CPP/7zip/Archive/Cab/CabHeader.cpp b/CPP/7zip/Archive/Cab/CabHeader.cpp
index 370a2f1e..370a2f1e 100644..100755
--- a/CPP/7zip/Archive/Cab/CabHeader.cpp
+++ b/CPP/7zip/Archive/Cab/CabHeader.cpp
diff --git a/CPP/7zip/Archive/Cab/CabHeader.h b/CPP/7zip/Archive/Cab/CabHeader.h
index 2f2bd109..2f2bd109 100644..100755
--- a/CPP/7zip/Archive/Cab/CabHeader.h
+++ b/CPP/7zip/Archive/Cab/CabHeader.h
diff --git a/CPP/7zip/Archive/Cab/CabIn.cpp b/CPP/7zip/Archive/Cab/CabIn.cpp
index e11ce9d0..e11ce9d0 100644..100755
--- a/CPP/7zip/Archive/Cab/CabIn.cpp
+++ b/CPP/7zip/Archive/Cab/CabIn.cpp
diff --git a/CPP/7zip/Archive/Cab/CabIn.h b/CPP/7zip/Archive/Cab/CabIn.h
index 39586d12..39586d12 100644..100755
--- a/CPP/7zip/Archive/Cab/CabIn.h
+++ b/CPP/7zip/Archive/Cab/CabIn.h
diff --git a/CPP/7zip/Archive/Cab/CabItem.h b/CPP/7zip/Archive/Cab/CabItem.h
index 9a912d5e..9a912d5e 100644..100755
--- a/CPP/7zip/Archive/Cab/CabItem.h
+++ b/CPP/7zip/Archive/Cab/CabItem.h
diff --git a/CPP/7zip/Archive/Cab/CabRegister.cpp b/CPP/7zip/Archive/Cab/CabRegister.cpp
index 0b5cc93a..0b5cc93a 100644..100755
--- a/CPP/7zip/Archive/Cab/CabRegister.cpp
+++ b/CPP/7zip/Archive/Cab/CabRegister.cpp
diff --git a/CPP/7zip/Archive/Cab/StdAfx.h b/CPP/7zip/Archive/Cab/StdAfx.h
index 2854ff3e..2854ff3e 100644..100755
--- a/CPP/7zip/Archive/Cab/StdAfx.h
+++ b/CPP/7zip/Archive/Cab/StdAfx.h
diff --git a/CPP/7zip/Archive/Chm/ChmHandler.cpp b/CPP/7zip/Archive/Chm/ChmHandler.cpp
index 03e7ddd2..03e7ddd2 100644..100755
--- a/CPP/7zip/Archive/Chm/ChmHandler.cpp
+++ b/CPP/7zip/Archive/Chm/ChmHandler.cpp
diff --git a/CPP/7zip/Archive/Chm/ChmHandler.h b/CPP/7zip/Archive/Chm/ChmHandler.h
index 884f391b..884f391b 100644..100755
--- a/CPP/7zip/Archive/Chm/ChmHandler.h
+++ b/CPP/7zip/Archive/Chm/ChmHandler.h
diff --git a/CPP/7zip/Archive/Chm/ChmIn.cpp b/CPP/7zip/Archive/Chm/ChmIn.cpp
index f4916b68..f4916b68 100644..100755
--- a/CPP/7zip/Archive/Chm/ChmIn.cpp
+++ b/CPP/7zip/Archive/Chm/ChmIn.cpp
diff --git a/CPP/7zip/Archive/Chm/ChmIn.h b/CPP/7zip/Archive/Chm/ChmIn.h
index f7b75d81..7cba0c71 100644..100755
--- a/CPP/7zip/Archive/Chm/ChmIn.h
+++ b/CPP/7zip/Archive/Chm/ChmIn.h
@@ -84,6 +84,11 @@ struct CResetTable
// unsigned BlockSizeBits;
CRecordVector<UInt64> ResetOffsets;
+ CResetTable():
+ UncompressedSize(0),
+ CompressedSize(0)
+ {}
+
bool GetCompressedSizeOfBlocks(UInt64 blockIndex, UInt32 numBlocks, UInt64 &size) const
{
if (blockIndex >= ResetOffsets.Size())
@@ -118,6 +123,12 @@ struct CLzxInfo
CResetTable ResetTable;
+ CLzxInfo():
+ Version(0),
+ ResetIntervalBits(0),
+ CacheSize(0)
+ {}
+
unsigned GetNumDictBits() const
{
if (Version == 2 || Version == 3)
diff --git a/CPP/7zip/Archive/Chm/StdAfx.h b/CPP/7zip/Archive/Chm/StdAfx.h
index 2854ff3e..2854ff3e 100644..100755
--- a/CPP/7zip/Archive/Chm/StdAfx.h
+++ b/CPP/7zip/Archive/Chm/StdAfx.h
diff --git a/CPP/7zip/Archive/ComHandler.cpp b/CPP/7zip/Archive/ComHandler.cpp
index a1f643b7..a1f643b7 100644..100755
--- a/CPP/7zip/Archive/ComHandler.cpp
+++ b/CPP/7zip/Archive/ComHandler.cpp
diff --git a/CPP/7zip/Archive/Common/CoderMixer2.cpp b/CPP/7zip/Archive/Common/CoderMixer2.cpp
index c8b67bd4..c8b67bd4 100644..100755
--- a/CPP/7zip/Archive/Common/CoderMixer2.cpp
+++ b/CPP/7zip/Archive/Common/CoderMixer2.cpp
diff --git a/CPP/7zip/Archive/Common/CoderMixer2.h b/CPP/7zip/Archive/Common/CoderMixer2.h
index f099ac3e..f099ac3e 100644..100755
--- a/CPP/7zip/Archive/Common/CoderMixer2.h
+++ b/CPP/7zip/Archive/Common/CoderMixer2.h
diff --git a/CPP/7zip/Archive/Common/DummyOutStream.cpp b/CPP/7zip/Archive/Common/DummyOutStream.cpp
index 7c4f5487..7c4f5487 100644..100755
--- a/CPP/7zip/Archive/Common/DummyOutStream.cpp
+++ b/CPP/7zip/Archive/Common/DummyOutStream.cpp
diff --git a/CPP/7zip/Archive/Common/DummyOutStream.h b/CPP/7zip/Archive/Common/DummyOutStream.h
index b5a51fc0..b5a51fc0 100644..100755
--- a/CPP/7zip/Archive/Common/DummyOutStream.h
+++ b/CPP/7zip/Archive/Common/DummyOutStream.h
diff --git a/CPP/7zip/Archive/Common/FindSignature.cpp b/CPP/7zip/Archive/Common/FindSignature.cpp
index fc952fa8..fc952fa8 100644..100755
--- a/CPP/7zip/Archive/Common/FindSignature.cpp
+++ b/CPP/7zip/Archive/Common/FindSignature.cpp
diff --git a/CPP/7zip/Archive/Common/FindSignature.h b/CPP/7zip/Archive/Common/FindSignature.h
index c359b9ed..c359b9ed 100644..100755
--- a/CPP/7zip/Archive/Common/FindSignature.h
+++ b/CPP/7zip/Archive/Common/FindSignature.h
diff --git a/CPP/7zip/Archive/Common/HandlerOut.cpp b/CPP/7zip/Archive/Common/HandlerOut.cpp
index 89012204..1b9a93eb 100644..100755
--- a/CPP/7zip/Archive/Common/HandlerOut.cpp
+++ b/CPP/7zip/Archive/Common/HandlerOut.cpp
@@ -240,34 +240,42 @@ void CSingleMethodProps::Init()
}
+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);
- continue;
- }
- {
- HRESULT hres;
- if (SetCommonProperty(name, value, hres))
- {
- RINOK(hres)
- continue;
- }
- }
- RINOK(ParseMethodFromPROPVARIANT(names[i], value));
+ RINOK(SetProperty(names[i], values[i]));
}
return S_OK;
@@ -275,4 +283,29 @@ HRESULT CSingleMethodProps::SetProperties(const wchar_t * const *names, const PR
#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/CPP/7zip/Archive/Common/HandlerOut.h b/CPP/7zip/Archive/Common/HandlerOut.h
index b3d07e9e..41ee189d 100644..100755
--- a/CPP/7zip/Archive/Common/HandlerOut.h
+++ b/CPP/7zip/Archive/Common/HandlerOut.h
@@ -16,6 +16,7 @@ class CCommonMethodProps
protected:
void InitCommon()
{
+ // _Write_MTime = true;
#ifndef _7ZIP_ST
_numProcessors = _numThreads = NWindows::NSystem::GetNumberOfProcessors();
_numThreads_WasForced = false;
@@ -118,11 +119,36 @@ public:
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/CPP/7zip/Archive/Common/InStreamWithCRC.cpp b/CPP/7zip/Archive/Common/InStreamWithCRC.cpp
index a2d68832..a2d68832 100644..100755
--- a/CPP/7zip/Archive/Common/InStreamWithCRC.cpp
+++ b/CPP/7zip/Archive/Common/InStreamWithCRC.cpp
diff --git a/CPP/7zip/Archive/Common/InStreamWithCRC.h b/CPP/7zip/Archive/Common/InStreamWithCRC.h
index 31b761e4..31b761e4 100644..100755
--- a/CPP/7zip/Archive/Common/InStreamWithCRC.h
+++ b/CPP/7zip/Archive/Common/InStreamWithCRC.h
diff --git a/CPP/7zip/Archive/Common/ItemNameUtils.cpp b/CPP/7zip/Archive/Common/ItemNameUtils.cpp
index 905a863d..8caf1d14 100644..100755
--- a/CPP/7zip/Archive/Common/ItemNameUtils.cpp
+++ b/CPP/7zip/Archive/Common/ItemNameUtils.cpp
@@ -79,6 +79,29 @@ void ReplaceToOsSlashes_Remove_TailSlash(UString &name, bool
}
+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
diff --git a/CPP/7zip/Archive/Common/ItemNameUtils.h b/CPP/7zip/Archive/Common/ItemNameUtils.h
index 6a4d6c71..3f5f4e8a 100644..100755
--- a/CPP/7zip/Archive/Common/ItemNameUtils.h
+++ b/CPP/7zip/Archive/Common/ItemNameUtils.h
@@ -14,6 +14,8 @@ 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);
diff --git a/CPP/7zip/Archive/Common/MultiStream.cpp b/CPP/7zip/Archive/Common/MultiStream.cpp
index 162fc928..162fc928 100644..100755
--- a/CPP/7zip/Archive/Common/MultiStream.cpp
+++ b/CPP/7zip/Archive/Common/MultiStream.cpp
diff --git a/CPP/7zip/Archive/Common/MultiStream.h b/CPP/7zip/Archive/Common/MultiStream.h
index c10cd455..c10cd455 100644..100755
--- a/CPP/7zip/Archive/Common/MultiStream.h
+++ b/CPP/7zip/Archive/Common/MultiStream.h
diff --git a/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp b/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp
index f955c225..f955c225 100644..100755
--- a/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp
+++ b/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp
diff --git a/CPP/7zip/Archive/Common/OutStreamWithCRC.h b/CPP/7zip/Archive/Common/OutStreamWithCRC.h
index 09b899bb..09b899bb 100644..100755
--- a/CPP/7zip/Archive/Common/OutStreamWithCRC.h
+++ b/CPP/7zip/Archive/Common/OutStreamWithCRC.h
diff --git a/CPP/7zip/Archive/Common/OutStreamWithSha1.cpp b/CPP/7zip/Archive/Common/OutStreamWithSha1.cpp
index ac26edf7..ac26edf7 100644..100755
--- a/CPP/7zip/Archive/Common/OutStreamWithSha1.cpp
+++ b/CPP/7zip/Archive/Common/OutStreamWithSha1.cpp
diff --git a/CPP/7zip/Archive/Common/OutStreamWithSha1.h b/CPP/7zip/Archive/Common/OutStreamWithSha1.h
index 5a7bfef3..5a7bfef3 100644..100755
--- a/CPP/7zip/Archive/Common/OutStreamWithSha1.h
+++ b/CPP/7zip/Archive/Common/OutStreamWithSha1.h
diff --git a/CPP/7zip/Archive/Common/ParseProperties.cpp b/CPP/7zip/Archive/Common/ParseProperties.cpp
index 63e4f3ef..63e4f3ef 100644..100755
--- a/CPP/7zip/Archive/Common/ParseProperties.cpp
+++ b/CPP/7zip/Archive/Common/ParseProperties.cpp
diff --git a/CPP/7zip/Archive/Common/ParseProperties.h b/CPP/7zip/Archive/Common/ParseProperties.h
index 1038a8c0..1038a8c0 100644..100755
--- a/CPP/7zip/Archive/Common/ParseProperties.h
+++ b/CPP/7zip/Archive/Common/ParseProperties.h
diff --git a/CPP/7zip/Archive/Common/StdAfx.h b/CPP/7zip/Archive/Common/StdAfx.h
index 2854ff3e..2854ff3e 100644..100755
--- a/CPP/7zip/Archive/Common/StdAfx.h
+++ b/CPP/7zip/Archive/Common/StdAfx.h
diff --git a/CPP/7zip/Archive/CpioHandler.cpp b/CPP/7zip/Archive/CpioHandler.cpp
index ffdab16c..b7e7564f 100644..100755
--- a/CPP/7zip/Archive/CpioHandler.cpp
+++ b/CPP/7zip/Archive/CpioHandler.cpp
@@ -652,11 +652,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidMTime:
{
if (item.MTime != 0)
- {
- FILETIME utc;
- NTime::UnixTimeToFileTime(item.MTime, utc);
- prop = utc;
- }
+ PropVariant_SetFrom_UnixTime(prop, item.MTime);
break;
}
case kpidPosixAttrib: prop = item.Mode; break;
diff --git a/CPP/7zip/Archive/CramfsHandler.cpp b/CPP/7zip/Archive/CramfsHandler.cpp
index 0f123321..0f123321 100644..100755
--- a/CPP/7zip/Archive/CramfsHandler.cpp
+++ b/CPP/7zip/Archive/CramfsHandler.cpp
diff --git a/CPP/7zip/Archive/DeflateProps.cpp b/CPP/7zip/Archive/DeflateProps.cpp
index ca3dc6f5..ca3dc6f5 100644..100755
--- a/CPP/7zip/Archive/DeflateProps.cpp
+++ b/CPP/7zip/Archive/DeflateProps.cpp
diff --git a/CPP/7zip/Archive/DeflateProps.h b/CPP/7zip/Archive/DeflateProps.h
index 9fd2c2e9..9fd2c2e9 100644..100755
--- a/CPP/7zip/Archive/DeflateProps.h
+++ b/CPP/7zip/Archive/DeflateProps.h
diff --git a/CPP/7zip/Archive/DllExports.cpp b/CPP/7zip/Archive/DllExports.cpp
index 7aee235e..7aee235e 100644..100755
--- a/CPP/7zip/Archive/DllExports.cpp
+++ b/CPP/7zip/Archive/DllExports.cpp
diff --git a/CPP/7zip/Archive/DllExports2.cpp b/CPP/7zip/Archive/DllExports2.cpp
index 967a7cbf..1f714861 100644..100755
--- a/CPP/7zip/Archive/DllExports2.cpp
+++ b/CPP/7zip/Archive/DllExports2.cpp
@@ -125,6 +125,24 @@ STDAPI SetCaseSensitive(Int32 caseSensitive)
return S_OK;
}
+/*
+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 EXTERNAL_CODECS
CExternalCodecs g_ExternalCodecs;
diff --git a/CPP/7zip/Archive/DmgHandler.cpp b/CPP/7zip/Archive/DmgHandler.cpp
index 1f2ca264..1f2ca264 100644..100755
--- a/CPP/7zip/Archive/DmgHandler.cpp
+++ b/CPP/7zip/Archive/DmgHandler.cpp
diff --git a/CPP/7zip/Archive/ElfHandler.cpp b/CPP/7zip/Archive/ElfHandler.cpp
index efcde95d..efcde95d 100644..100755
--- a/CPP/7zip/Archive/ElfHandler.cpp
+++ b/CPP/7zip/Archive/ElfHandler.cpp
diff --git a/CPP/7zip/Archive/ExtHandler.cpp b/CPP/7zip/Archive/ExtHandler.cpp
index 6c095d9a..01e12edc 100644..100755
--- a/CPP/7zip/Archive/ExtHandler.cpp
+++ b/CPP/7zip/Archive/ExtHandler.cpp
@@ -343,6 +343,8 @@ struct CHeader
bool UseGdtChecksum() const { return (FeatureRoCompat & RO_COMPAT_GDT_CSUM) != 0; }
bool UseMetadataChecksum() const { return (FeatureRoCompat & RO_COMPAT_METADATA_CSUM) != 0; }
+ UInt64 GetPhySize() const { return NumBlocks << BlockBits; }
+
bool Parse(const Byte *p);
};
@@ -638,7 +640,7 @@ struct CNode
CExtTime MTime;
CExtTime ATime;
CExtTime CTime;
- // CExtTime InodeChangeTime;
+ CExtTime ChangeTime;
// CExtTime DTime;
UInt64 NumBlocks;
@@ -674,14 +676,14 @@ bool CNode::Parse(const Byte *p, const CHeader &_h)
ATime.Extra = 0;
CTime.Extra = 0;
CTime.Val = 0;
- // InodeChangeTime.Extra = 0;
+ ChangeTime.Extra = 0;
// DTime.Extra = 0;
LE_16 (0x00, Mode);
LE_16 (0x02, Uid);
LE_32 (0x04, FileSize);
LE_32 (0x08, ATime.Val);
- // LE_32 (0x0C, InodeChangeTime.Val);
+ LE_32 (0x0C, ChangeTime.Val);
LE_32 (0x10, MTime.Val);
// LE_32 (0x14, DTime.Val);
LE_16 (0x18, Gid);
@@ -742,7 +744,7 @@ bool CNode::Parse(const Byte *p, const CHeader &_h)
{
// UInt16 checksumUpper;
// LE_16 (0x82, checksumUpper);
- // LE_32 (0x84, InodeChangeTime.Extra);
+ LE_32 (0x84, ChangeTime.Extra);
LE_32 (0x88, MTime.Extra);
LE_32 (0x8C, ATime.Extra);
LE_32 (0x90, CTime.Val);
@@ -1148,7 +1150,7 @@ HRESULT CHandler::Open2(IInStream *inStream)
}
_isArc = true;
- _phySize = _h.NumBlocks << _h.BlockBits;
+ _phySize = _h.GetPhySize();
if (_openCallback)
{
@@ -1744,8 +1746,8 @@ static const UInt32 kProps[] =
kpidLinks,
kpidSymLink,
kpidCharacts,
- kpidUser,
- kpidGroup
+ kpidUserId,
+ kpidGroupId
};
@@ -1792,11 +1794,7 @@ static void StringToProp(bool isUTF, const char *s, unsigned size, NCOM::CPropVa
static void UnixTimeToProp(UInt32 val, NCOM::CPropVariant &prop)
{
if (val != 0)
- {
- FILETIME ft;
- NTime::UnixTimeToFileTime(val, ft);
- prop = ft;
- }
+ PropVariant_SetFrom_UnixTime(prop, val);
}
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
@@ -1988,15 +1986,19 @@ static void ExtTimeToProp(const CExtTime &t, NCOM::CPropVariant &prop)
return;
FILETIME ft;
+ unsigned low100ns = 0;
// if (t.Extra != 0)
{
// 1901-2446 :
Int64 v = (Int64)(Int32)t.Val;
v += (UInt64)(t.Extra & 3) << 32; // 2 low bits are offset for main timestamp
- UInt64 ft64 = NTime::UnixTime64ToFileTime64(v);
+ UInt64 ft64 = NTime::UnixTime64_To_FileTime64(v);
const UInt32 ns = (t.Extra >> 2);
if (ns < 1000000000)
+ {
ft64 += ns / 100;
+ low100ns = (unsigned)(ns % 100);
+ }
ft.dwLowDateTime = (DWORD)ft64;
ft.dwHighDateTime = (DWORD)(ft64 >> 32);
}
@@ -2011,7 +2013,7 @@ static void ExtTimeToProp(const CExtTime &t, NCOM::CPropVariant &prop)
// NTime::UnixTimeToFileTime(t.Val, ft); // for
}
*/
- prop = ft;
+ prop.SetAsTimeFrom_FT_Prec_Ns100(ft, k_PropVar_TimePrec_1ns, low100ns);
}
@@ -2103,10 +2105,9 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidCTime: ExtTimeToProp(node.CTime, prop); break;
case kpidATime: ExtTimeToProp(node.ATime, prop); break;
// case kpidDTime: ExtTimeToProp(node.DTime, prop); break;
- // case kpidChangeTime: ExtTimeToProp(node.InodeChangeTime, prop); break;
-
- case kpidUser: prop = (UInt32)node.Uid; break;
- case kpidGroup: prop = (UInt32)node.Gid; break;
+ case kpidChangeTime: ExtTimeToProp(node.ChangeTime, prop); break;
+ case kpidUserId: prop = (UInt32)node.Uid; break;
+ case kpidGroupId: prop = (UInt32)node.Gid; break;
case kpidLinks: prop = node.NumLinks; break;
case kpidINode: prop = (UInt32)item.Node; break;
case kpidStreamId: if (!isDir) prop = (UInt32)item.Node; break;
@@ -2827,17 +2828,29 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
}
-API_FUNC_static_IsArc IsArc_Ext(const Byte *p, size_t size)
+API_FUNC_IsArc IsArc_Ext_PhySize(const Byte *p, size_t size, UInt64 *phySize);
+API_FUNC_IsArc IsArc_Ext_PhySize(const Byte *p, size_t size, UInt64 *phySize)
{
+ if (phySize)
+ *phySize = 0;
if (size < kHeaderSize)
return k_IsArc_Res_NEED_MORE;
CHeader h;
if (!h.Parse(p + kHeaderDataOffset))
return k_IsArc_Res_NO;
+ if (phySize)
+ *phySize = h.GetPhySize();
return k_IsArc_Res_YES;
}
+
+
+API_FUNC_IsArc IsArc_Ext(const Byte *p, size_t size);
+API_FUNC_IsArc IsArc_Ext(const Byte *p, size_t size)
+{
+ return IsArc_Ext_PhySize(p, size, NULL);
}
+
static const Byte k_Signature[] = { 0x53, 0xEF };
REGISTER_ARC_I(
diff --git a/CPP/7zip/Archive/FatHandler.cpp b/CPP/7zip/Archive/FatHandler.cpp
index 1cbc8508..826b4fd1 100644..100755
--- a/CPP/7zip/Archive/FatHandler.cpp
+++ b/CPP/7zip/Archive/FatHandler.cpp
@@ -111,14 +111,14 @@ static int GetLog(UInt32 num)
static const UInt32 kHeaderSize = 512;
-API_FUNC_static_IsArc IsArc_Fat(const Byte *p, size_t size)
+API_FUNC_IsArc IsArc_Fat(const Byte *p, size_t size);
+API_FUNC_IsArc IsArc_Fat(const Byte *p, size_t size)
{
if (size < kHeaderSize)
return k_IsArc_Res_NEED_MORE;
CHeader h;
return h.Parse(p) ? k_IsArc_Res_YES : k_IsArc_Res_NO;
}
-}
bool CHeader::Parse(const Byte *p)
{
@@ -846,17 +846,18 @@ static const CStatProp kArcProps[] =
IMP_IInArchive_Props
IMP_IInArchive_ArcProps_WITH_NAME
+
static void FatTimeToProp(UInt32 dosTime, UInt32 ms10, NWindows::NCOM::CPropVariant &prop)
{
FILETIME localFileTime, utc;
- if (NWindows::NTime::DosTimeToFileTime(dosTime, localFileTime))
+ if (NWindows::NTime::DosTime_To_FileTime(dosTime, localFileTime))
if (LocalFileTimeToFileTime(&localFileTime, &utc))
{
UInt64 t64 = (((UInt64)utc.dwHighDateTime) << 32) + utc.dwLowDateTime;
t64 += ms10 * 100000;
utc.dwLowDateTime = (DWORD)t64;
utc.dwHighDateTime = (DWORD)(t64 >> 32);
- prop = utc;
+ prop.SetAsTimeFrom_FT_Prec(utc, k_PropVar_TimePrec_Base + 2);
}
}
@@ -892,7 +893,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
case kpidPhySize: prop = PhySize; break;
case kpidFreeSpace: prop = (UInt64)NumFreeClusters << Header.ClusterSizeLog; break;
case kpidHeadersSize: prop = GetHeadersSize(); break;
- case kpidMTime: if (VolItemDefined) FatTimeToProp(VolItem.MTime, 0, prop); break;
+ case kpidMTime: if (VolItemDefined) PropVariant_SetFrom_DosTime(prop, VolItem.MTime); break;
case kpidShortComment:
case kpidVolumeName: if (VolItemDefined) prop = VolItem.GetVolName(); break;
case kpidNumFats: if (Header.NumFats != 2) prop = Header.NumFats; break;
@@ -920,9 +921,9 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidPath: prop = GetItemPath(index); break;
case kpidShortName: prop = item.GetShortName(); break;
case kpidIsDir: prop = item.IsDir(); break;
- case kpidMTime: FatTimeToProp(item.MTime, 0, prop); break;
+ case kpidMTime: PropVariant_SetFrom_DosTime(prop, item.MTime); break;
case kpidCTime: FatTimeToProp(item.CTime, item.CTime2, prop); break;
- case kpidATime: FatTimeToProp(((UInt32)item.ADate << 16), 0, prop); break;
+ case kpidATime: PropVariant_SetFrom_DosTime(prop, ((UInt32)item.ADate << 16)); break;
case kpidAttrib: prop = (UInt32)item.Attrib; break;
case kpidSize: if (!item.IsDir()) prop = item.Size; break;
case kpidPackSize: if (!item.IsDir()) prop = Header.GetFilePackSize(item.Size); break;
diff --git a/CPP/7zip/Archive/FlvHandler.cpp b/CPP/7zip/Archive/FlvHandler.cpp
index 97a7c268..97a7c268 100644..100755
--- a/CPP/7zip/Archive/FlvHandler.cpp
+++ b/CPP/7zip/Archive/FlvHandler.cpp
diff --git a/CPP/7zip/Archive/GptHandler.cpp b/CPP/7zip/Archive/GptHandler.cpp
index 2b3a673b..0d2caa3d 100644..100755
--- a/CPP/7zip/Archive/GptHandler.cpp
+++ b/CPP/7zip/Archive/GptHandler.cpp
@@ -23,6 +23,11 @@
using namespace NWindows;
namespace NArchive {
+
+namespace NFat {
+API_FUNC_IsArc IsArc_Fat(const Byte *p, size_t size);
+}
+
namespace NGpt {
#define SIGNATURE { 'E', 'F', 'I', ' ', 'P', 'A', 'R', 'T', 0, 0, 1, 0 }
@@ -51,6 +56,7 @@ struct CPartition
UInt64 FirstLba;
UInt64 LastLba;
UInt64 Flags;
+ const char *Ext; // detected later
Byte Name[kNameLen * 2];
bool IsUnused() const
@@ -73,6 +79,7 @@ struct CPartition
LastLba = Get64(p + 40);
Flags = Get64(p + 48);
memcpy(Name, p + 56, kNameLen * 2);
+ Ext = NULL;
}
};
@@ -252,6 +259,28 @@ HRESULT CHandler::Open2(IInStream *stream)
return S_OK;
}
+
+
+static const unsigned k_Ntfs_Fat_HeaderSize = 512;
+
+static const Byte k_NtfsSignature[] = { 'N', 'T', 'F', 'S', ' ', ' ', ' ', ' ', 0 };
+
+static bool IsNtfs(const Byte *p)
+{
+ if (p[0x1FE] != 0x55 || p[0x1FF] != 0xAA)
+ return false;
+ if (memcmp(p + 3, k_NtfsSignature, ARRAY_SIZE(k_NtfsSignature)) != 0)
+ return false;
+ switch (p[0])
+ {
+ case 0xE9: /* codeOffset = 3 + (Int16)Get16(p + 1); */ break;
+ case 0xEB: if (p[2] != 0x90) return false; /* codeOffset = 2 + (int)(signed char)p[1]; */ break;
+ default: return false;
+ }
+ return true;
+}
+
+
STDMETHODIMP CHandler::Open(IInStream *stream,
const UInt64 * /* maxCheckStartPosition */,
IArchiveOpenCallback * /* openArchiveCallback */)
@@ -260,6 +289,42 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
Close();
RINOK(Open2(stream));
_stream = stream;
+
+ FOR_VECTOR (fileIndex, _items)
+ {
+ CPartition &item = _items[fileIndex];
+ const int typeIndex = FindPartType(item.Type);
+ if (typeIndex < 0)
+ continue;
+ const CPartType &t = kPartTypes[(unsigned)typeIndex];
+ if (t.Ext)
+ {
+ item.Ext = t.Ext;
+ continue;
+ }
+ if (t.Type && IsString1PrefixedByString2_NoCase_Ascii(t.Type, "Windows"))
+ {
+ CMyComPtr<ISequentialInStream> inStream;
+ if (GetStream(fileIndex, &inStream) == S_OK && inStream)
+ {
+ Byte temp[k_Ntfs_Fat_HeaderSize];
+ if (ReadStream_FAIL(inStream, temp, k_Ntfs_Fat_HeaderSize) == S_OK)
+ {
+ if (IsNtfs(temp))
+ {
+ item.Ext = "ntfs";
+ continue;
+ }
+ if (NFat::IsArc_Fat(temp, k_Ntfs_Fat_HeaderSize) == k_IsArc_Res_YES)
+ {
+ item.Ext = "fat";
+ continue;
+ }
+ }
+ }
+ }
+ }
+
return S_OK;
COM_TRY_END
}
@@ -355,13 +420,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
}
{
s += '.';
- const char *ext = NULL;
- int typeIndex = FindPartType(item.Type);
- if (typeIndex >= 0)
- ext = kPartTypes[(unsigned)typeIndex].Ext;
- if (!ext)
- ext = "img";
- s += ext;
+ s += (item.Ext ? item.Ext : "img");
}
prop = s;
break;
@@ -375,7 +434,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{
char s[48];
const char *res;
- int typeIndex = FindPartType(item.Type);
+ const int typeIndex = FindPartType(item.Type);
if (typeIndex >= 0 && kPartTypes[(unsigned)typeIndex].Type)
res = kPartTypes[(unsigned)typeIndex].Type;
else
diff --git a/CPP/7zip/Archive/GzHandler.cpp b/CPP/7zip/Archive/GzHandler.cpp
index 0054840d..35e642ec 100644..100755
--- a/CPP/7zip/Archive/GzHandler.cpp
+++ b/CPP/7zip/Archive/GzHandler.cpp
@@ -475,6 +475,7 @@ class CHandler:
NDecoder::CCOMCoder *_decoderSpec;
CSingleMethodProps _props;
+ CHandlerTimeOptions _timeOptions;
public:
MY_UNKNOWN_IMP4(
@@ -487,8 +488,15 @@ public:
STDMETHOD(OpenSeq)(ISequentialInStream *stream);
STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps);
- CHandler()
+ CHandler():
+ _isArc(false),
+ _decoderSpec(NULL)
+ {}
+
+ void CreateDecoder()
{
+ if (_decoder)
+ return;
_decoderSpec = new NDecoder::CCOMCoder;
_decoder = _decoderSpec;
}
@@ -528,7 +536,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
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;
prop = v;
@@ -567,12 +575,13 @@ STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIAN
break;
// case kpidComment: if (_item.CommentIsPresent()) prop = MultiByteToUnicodeString(_item.Comment, CP_ACP); break;
case kpidMTime:
+ // gzip specification: MTIME = 0 means no time stamp is available.
if (_item.Time != 0)
- {
- FILETIME utc;
- NTime::UnixTimeToFileTime(_item.Time, utc);
- prop = utc;
- }
+ PropVariant_SetFrom_UnixTime(prop, _item.Time);
+ break;
+ case kpidTimeType:
+ if (_item.Time != 0)
+ prop = (UInt32)NFileTimeType::kUnix;
break;
case kpidSize:
{
@@ -644,6 +653,7 @@ STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream)
try
{
Close();
+ CreateDecoder();
_decoderSpec->SetInStream(stream);
_decoderSpec->InitInStream(true);
RINOK(_item.ReadHeader(_decoderSpec));
@@ -672,7 +682,8 @@ STDMETHODIMP CHandler::Close()
_headerSize = 0;
_stream.Release();
- _decoderSpec->ReleaseInStream();
+ if (_decoder)
+ _decoderSpec->ReleaseInStream();
return S_OK;
}
@@ -699,6 +710,8 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
extractCallback->PrepareOperation(askMode);
+ CreateDecoder();
+
COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC;
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
outStreamSpec->SetStream(realOutStream);
@@ -873,21 +886,99 @@ static const Byte kHostOS =
NHostOS::kUnix;
#endif
+
+/*
+static HRESULT ReportItemProp(IArchiveUpdateCallbackArcProp *reportArcProp, PROPID propID, const PROPVARIANT *value)
+{
+ return reportArcProp->ReportProp(NEventIndexType::kOutArcIndex, 0, propID, value);
+}
+
+static HRESULT ReportArcProp(IArchiveUpdateCallbackArcProp *reportArcProp, PROPID propID, const PROPVARIANT *value)
+{
+ return reportArcProp->ReportProp(NEventIndexType::kArcProp, 0, propID, value);
+}
+
+static HRESULT ReportArcProps(IArchiveUpdateCallbackArcProp *reportArcProp,
+ const CItem &item,
+ bool needTime,
+ bool needCrc,
+ const UInt64 *unpackSize)
+{
+ NCOM::CPropVariant timeProp;
+ NCOM::CPropVariant sizeProp;
+ if (needTime)
+ {
+ FILETIME ft;
+ NTime::UnixTimeToFileTime(item.Time, ft);
+ timeProp.SetAsTimeFrom_FT_Prec(ft, k_PropVar_TimePrec_Unix);
+ }
+ if (unpackSize)
+ {
+ sizeProp = *unpackSize;
+ RINOK(ReportItemProp(reportArcProp, kpidSize, &sizeProp));
+ }
+ if (needCrc)
+ {
+ NCOM::CPropVariant prop;
+ prop = item.Crc;
+ RINOK(ReportItemProp(reportArcProp, kpidCRC, &prop));
+ }
+ {
+ RINOK(ReportItemProp(reportArcProp, kpidMTime, &timeProp));
+ }
+
+ RINOK(reportArcProp->ReportFinished(NEventIndexType::kOutArcIndex, 0, NArchive::NUpdate::NOperationResult::kOK));
+
+ if (unpackSize)
+ {
+ RINOK(ReportArcProp(reportArcProp, kpidSize, &sizeProp));
+ }
+ {
+ RINOK(ReportArcProp(reportArcProp, kpidComboMTime, &timeProp));
+ }
+ return S_OK;
+}
+*/
+
static HRESULT UpdateArchive(
ISequentialOutStream *outStream,
UInt64 unpackSize,
CItem &item,
const CSingleMethodProps &props,
- IArchiveUpdateCallback *updateCallback)
+ const CHandlerTimeOptions &timeOptions,
+ IArchiveUpdateCallback *updateCallback
+ // , IArchiveUpdateCallbackArcProp *reportArcProp
+ )
{
- UInt64 complexity = 0;
- RINOK(updateCallback->SetTotal(unpackSize));
- RINOK(updateCallback->SetCompleted(&complexity));
-
+ UInt64 unpackSizeReal;
+ {
CMyComPtr<ISequentialInStream> fileInStream;
RINOK(updateCallback->GetStream(0, &fileInStream));
+ if (!fileInStream)
+ return S_FALSE;
+
+ {
+ CMyComPtr<IStreamGetProps> getProps;
+ fileInStream->QueryInterface(IID_IStreamGetProps, (void **)&getProps);
+ if (getProps)
+ {
+ FILETIME mTime;
+ UInt64 size;
+ if (getProps->GetProps(&size, NULL, NULL, &mTime, NULL) == S_OK)
+ {
+ unpackSize = size;
+ if (timeOptions.Write_MTime.Val)
+ NTime::FileTime_To_UnixTime(mTime, item.Time);
+ }
+ }
+ }
+
+ UInt64 complexity = 0;
+ RINOK(updateCallback->SetTotal(unpackSize));
+ RINOK(updateCallback->SetCompleted(&complexity));
+
CSequentialInStreamWithCRC *inStreamSpec = new CSequentialInStreamWithCRC;
CMyComPtr<ISequentialInStream> crcStream(inStreamSpec);
inStreamSpec->SetStream(fileInStream);
@@ -911,14 +1002,50 @@ static HRESULT UpdateArchive(
RINOK(deflateEncoder->Code(crcStream, outStream, NULL, NULL, progress));
item.Crc = inStreamSpec->GetCRC();
- item.Size32 = (UInt32)inStreamSpec->GetSize();
+ unpackSizeReal = inStreamSpec->GetSize();
+ item.Size32 = (UInt32)unpackSizeReal;
RINOK(item.WriteFooter(outStream));
+ }
+ /*
+ if (reportArcProp)
+ {
+ RINOK(ReportArcProps(reportArcProp,
+ item,
+ props._Write_MTime, // item.Time != 0,
+ true, // writeCrc
+ &unpackSizeReal));
+ }
+ */
return updateCallback->SetOperationResult(NUpdate::NOperationResult::kOK);
}
+
STDMETHODIMP CHandler::GetFileTimeType(UInt32 *timeType)
{
- *timeType = NFileTimeType::kUnix;
+ /*
+ if (_item.Time != 0)
+ {
+ we set NFileTimeType::kUnix in precision,
+ and we return NFileTimeType::kUnix in kpidTimeType
+ so GetFileTimeType() value is not used in any version of 7-zip.
+ }
+ else // (_item.Time == 0)
+ {
+ kpidMTime and kpidTimeType are not defined
+ before 22.00 : GetFileTimeType() value is used in GetUpdatePairInfoList();
+ 22.00 : GetFileTimeType() value is not used
+ }
+ */
+
+ UInt32 t;
+ t = NFileTimeType::kUnix;
+ if (_isArc ? (_item.Time == 0) : !_timeOptions.Write_MTime.Val)
+ {
+ t = GET_FileTimeType_NotDefined_for_GetFileTimeType;
+ // t = k_PropVar_TimePrec_1ns; // failed in 7-Zip 21
+ // t = (UInt32)(Int32)NFileTimeType::kNotDefined; // failed in 7-Zip 21
+ }
+ *timeType = t;
return S_OK;
}
@@ -936,6 +1063,11 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
return E_FAIL;
RINOK(updateCallback->GetUpdateItemInfo(0, &newData, &newProps, &indexInArchive));
+ /*
+ CMyComPtr<IArchiveUpdateCallbackArcProp> reportArcProp;
+ updateCallback->QueryInterface(IID_IArchiveUpdateCallbackArcProp, (void **)&reportArcProp);
+ */
+
CItem newItem;
if (!IntToBool(newProps))
@@ -945,11 +1077,12 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
else
{
newItem.HostOS = kHostOS;
+ if (_timeOptions.Write_MTime.Val)
{
NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(0, kpidMTime, &prop));
if (prop.vt == VT_FILETIME)
- NTime::FileTimeToUnixTime(prop.filetime, newItem.Time);
+ NTime::FileTime_To_UnixTime(prop.filetime, newItem.Time);
else if (prop.vt == VT_EMPTY)
newItem.Time = 0;
else
@@ -990,7 +1123,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
return E_INVALIDARG;
size = prop.uhVal.QuadPart;
}
- return UpdateArchive(outStream, size, newItem, _props, updateCallback);
+ return UpdateArchive(outStream, size, newItem, _props, _timeOptions, updateCallback);
}
if (indexInArchive != 0)
@@ -1022,6 +1155,14 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
}
RINOK(_stream->Seek((Int64)offset, STREAM_SEEK_SET, NULL));
+ /*
+ if (reportArcProp)
+ ReportArcProps(reportArcProp, newItem,
+ _props._Write_MTime,
+ false, // writeCrc
+ NULL); // unpacksize
+ */
+
return NCompress::CopyStream(_stream, outStream, progress);
COM_TRY_END
@@ -1029,16 +1170,48 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)
{
- return _props.SetProperties(names, values, numProps);
+ _timeOptions.Init();
+ _props.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];
+ {
+ bool processed = false;
+ RINOK(_timeOptions.Parse(name, value, processed));
+ if (processed)
+ {
+ if (_timeOptions.Write_CTime.Val ||
+ _timeOptions.Write_ATime.Val)
+ return E_INVALIDARG;
+ if ( _timeOptions.Prec != (UInt32)(Int32)-1
+ && _timeOptions.Prec != k_PropVar_TimePrec_0
+ && _timeOptions.Prec != k_PropVar_TimePrec_Unix
+ && _timeOptions.Prec != k_PropVar_TimePrec_HighPrec
+ && _timeOptions.Prec != k_PropVar_TimePrec_Base)
+ return E_INVALIDARG;
+ continue;
+ }
+ }
+ RINOK(_props.SetProperty(name, value));
+ }
+ return S_OK;
}
static const Byte k_Signature[] = { kSignature_0, kSignature_1, kSignature_2 };
REGISTER_ARC_IO(
"gzip", "gz gzip tgz tpz apk", "* * .tar .tar .tar", 0xEF,
- k_Signature,
- 0,
- NArcInfoFlags::kKeepName,
- IsArc_Gz)
+ k_Signature, 0,
+ NArcInfoFlags::kKeepName
+ | NArcInfoFlags::kMTime
+ | NArcInfoFlags::kMTime_Default
+ , TIME_PREC_TO_ARC_FLAGS_MASK (NFileTimeType::kUnix)
+ | TIME_PREC_TO_ARC_FLAGS_TIME_DEFAULT (NFileTimeType::kUnix)
+ , IsArc_Gz)
}}
diff --git a/CPP/7zip/Archive/HandlerCont.cpp b/CPP/7zip/Archive/HandlerCont.cpp
index 6f196de8..3cbfdacd 100644..100755
--- a/CPP/7zip/Archive/HandlerCont.cpp
+++ b/CPP/7zip/Archive/HandlerCont.cpp
@@ -14,6 +14,10 @@
namespace NArchive {
+namespace NExt {
+API_FUNC_IsArc IsArc_Ext(const Byte *p, size_t size);
+}
+
STDMETHODIMP CHandlerCont::Extract(const UInt32 *indices, UInt32 numItems,
Int32 testMode, IArchiveExtractCallback *extractCallback)
{
@@ -132,11 +136,12 @@ STDMETHODIMP CHandlerImg::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosit
}
static const Byte k_GDP_Signature[] = { 'E', 'F', 'I', ' ', 'P', 'A', 'R', 'T' };
-
+// static const Byte k_Ext_Signature[] = { 0x53, 0xEF };
+// static const unsigned k_Ext_Signature_offset = 0x438;
static const char *GetImgExt(ISequentialInStream *stream)
{
- const size_t kHeaderSize = 1 << 10;
+ const size_t kHeaderSize = 1 << 11;
Byte buf[kHeaderSize];
if (ReadStream_FAIL(stream, buf, kHeaderSize) == S_OK)
{
@@ -146,6 +151,8 @@ static const char *GetImgExt(ISequentialInStream *stream)
return "gpt";
return "mbr";
}
+ if (NExt::IsArc_Ext(buf, kHeaderSize) == k_IsArc_Res_YES)
+ return "ext";
}
return NULL;
}
@@ -208,6 +215,33 @@ STDMETHODIMP CHandlerImg::GetNumberOfItems(UInt32 *numItems)
return S_OK;
}
+
+class CHandlerImgProgress:
+ public ICompressProgressInfo,
+ public CMyUnknownImp
+{
+public:
+ CHandlerImg &Handler;
+ CMyComPtr<ICompressProgressInfo> _ratioProgress;
+
+ CHandlerImgProgress(CHandlerImg &handler) : Handler(handler) {}
+
+ // MY_UNKNOWN_IMP1(ICompressProgressInfo)
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
+};
+
+
+STDMETHODIMP CHandlerImgProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
+{
+ UInt64 inSize2;
+ if (Handler.Get_PackSizeProcessed(inSize2))
+ inSize = &inSize2;
+ return _ratioProgress->SetRatioInfo(inSize, outSize);
+}
+
+
STDMETHODIMP CHandlerImg::Extract(const UInt32 *indices, UInt32 numItems,
Int32 testMode, IArchiveExtractCallback *extractCallback)
{
@@ -227,10 +261,6 @@ STDMETHODIMP CHandlerImg::Extract(const UInt32 *indices, UInt32 numItems,
return S_OK;
RINOK(extractCallback->PrepareOperation(askMode));
- CLocalProgress *lps = new CLocalProgress;
- CMyComPtr<ICompressProgressInfo> progress = lps;
- lps->Init(extractCallback, false);
-
int opRes = NExtract::NOperationResult::kDataError;
ClearStreamVars();
@@ -242,6 +272,19 @@ STDMETHODIMP CHandlerImg::Extract(const UInt32 *indices, UInt32 numItems,
if (hres == S_OK && inStream)
{
+ CLocalProgress *lps = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> progress = lps;
+ lps->Init(extractCallback, false);
+
+ if (Init_PackSizeProcessed())
+ {
+ CHandlerImgProgress *imgProgressSpec = new CHandlerImgProgress(*this);
+ CMyComPtr<ICompressProgressInfo> imgProgress = imgProgressSpec;
+ imgProgressSpec->_ratioProgress = progress;
+ progress.Release();
+ progress = imgProgress;
+ }
+
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
diff --git a/CPP/7zip/Archive/HandlerCont.h b/CPP/7zip/Archive/HandlerCont.h
index 0b92d190..3c645929 100644..100755
--- a/CPP/7zip/Archive/HandlerCont.h
+++ b/CPP/7zip/Archive/HandlerCont.h
@@ -94,7 +94,19 @@ protected:
virtual HRESULT Open2(IInStream *stream, IArchiveOpenCallback *openCallback) = 0;
virtual void CloseAtError();
+
+ // returns (true), if Get_PackSizeProcessed() is required in Extract()
+ virtual bool Init_PackSizeProcessed()
+ {
+ return false;
+ }
public:
+ virtual bool Get_PackSizeProcessed(UInt64 &size)
+ {
+ size = 0;
+ return false;
+ }
+
MY_UNKNOWN_IMP3(IInArchive, IInArchiveGetStream, IInStream)
INTERFACE_IInArchive_Img(PURE)
diff --git a/CPP/7zip/Archive/HfsHandler.cpp b/CPP/7zip/Archive/HfsHandler.cpp
index b70a291f..f0a85f1a 100644..100755
--- a/CPP/7zip/Archive/HfsHandler.cpp
+++ b/CPP/7zip/Archive/HfsHandler.cpp
@@ -240,7 +240,7 @@ struct CItem
UInt32 ID;
UInt32 CTime;
UInt32 MTime;
- // UInt32 AttrMTime;
+ UInt32 AttrMTime;
UInt32 ATime;
// UInt32 BackupDate;
@@ -1000,7 +1000,7 @@ HRESULT CDatabase::LoadCatalog(const CFork &fork, const CObjectVector<CIdExtents
item.CTime = Get32(r + 0xC);
item.MTime = Get32(r + 0x10);
- // item.AttrMTime = Get32(r + 0x14);
+ item.AttrMTime = Get32(r + 0x14);
item.ATime = Get32(r + 0x18);
// item.BackupDate = Get32(r + 0x1C);
@@ -1404,6 +1404,7 @@ static const Byte kProps[] =
kpidCTime,
kpidMTime,
kpidATime,
+ kpidChangeTime,
kpidPosixAttrib
};
@@ -1421,9 +1422,11 @@ IMP_IInArchive_ArcProps
static void HfsTimeToProp(UInt32 hfsTime, NWindows::NCOM::CPropVariant &prop)
{
+ if (hfsTime == 0)
+ return;
FILETIME ft;
HfsTimeToFileTime(hfsTime, ft);
- prop = ft;
+ prop.SetAsTimeFrom_FT_Prec(ft, k_PropVar_TimePrec_Base);
}
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
@@ -1447,10 +1450,13 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
case kpidMTime: HfsTimeToProp(Header.MTime, prop); break;
case kpidCTime:
{
- FILETIME localFt, ft;
- HfsTimeToFileTime(Header.CTime, localFt);
- if (LocalFileTimeToFileTime(&localFt, &ft))
- prop = ft;
+ if (Header.CTime != 0)
+ {
+ FILETIME localFt, ft;
+ HfsTimeToFileTime(Header.CTime, localFt);
+ if (LocalFileTimeToFileTime(&localFt, &ft))
+ prop.SetAsTimeFrom_FT_Prec(ft, k_PropVar_TimePrec_Base);
+ }
break;
}
case kpidIsTree: prop = true; break;
@@ -1578,6 +1584,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidCTime: HfsTimeToProp(item.CTime, prop); break;
case kpidMTime: HfsTimeToProp(item.MTime, prop); break;
case kpidATime: HfsTimeToProp(item.ATime, prop); break;
+ case kpidChangeTime: HfsTimeToProp(item.AttrMTime, prop); break;
case kpidPosixAttrib: if (ref.AttrIndex < 0) prop = (UInt32)item.FileMode; break;
}
diff --git a/CPP/7zip/Archive/IArchive.h b/CPP/7zip/Archive/IArchive.h
index 6df76d26..9551dfaf 100644..100755
--- a/CPP/7zip/Archive/IArchive.h
+++ b/CPP/7zip/Archive/IArchive.h
@@ -38,9 +38,11 @@ namespace NFileTimeType
{
enum EEnum
{
- kWindows,
+ kNotDefined = -1,
+ kWindows = 0,
kUnix,
- kDOS
+ kDOS,
+ k1ns
};
}
@@ -60,8 +62,31 @@ namespace NArcInfoFlags
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(x) \
+ ((UInt32)1 << (NArcInfoTimeFlags::kTime_Prec_Mask_bit_index + (x)))
+
+#define TIME_PREC_TO_ARC_FLAGS_TIME_DEFAULT(x) \
+ ((UInt32)(x) << NArcInfoTimeFlags::kTime_Prec_Default_bit_index)
+
namespace NArchive
{
namespace NHandlerPropID
@@ -79,8 +104,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
};
}
@@ -123,6 +148,7 @@ namespace NArchive
kInArcIndex,
kBlockIndex,
kOutArcIndex
+ // kArcProp
};
}
@@ -133,7 +159,8 @@ namespace NArchive
enum
{
kOK = 0
- // , kError
+ // kError = 1,
+ // kError_FileChanged
};
}
}
@@ -461,9 +488,10 @@ namespace NUpdateNotifyOp
kSkip,
kDelete,
kHeader,
- kHashRead
-
- // kNumDefined
+ kHashRead,
+ kInFileChanged
+ // , kOpFinished
+ // , kNumDefined
};
};
@@ -493,6 +521,20 @@ ARCHIVE_INTERFACE(IArchiveGetDiskProperty, 0x84)
};
/*
+#define INTERFACE_IArchiveUpdateCallbackArcProp(x) \
+ STDMETHOD(ReportProp)(UInt32 indexType, UInt32 index, PROPID propID, const PROPVARIANT *value) x; \
+ STDMETHOD(ReportRawProp)(UInt32 indexType, UInt32 index, PROPID propID, const void *data, UInt32 dataSize, UInt32 propType) x; \
+ STDMETHOD(ReportFinished)(UInt32 indexType, UInt32 index, Int32 opRes) x; \
+ STDMETHOD(DoNeedArcProp)(PROPID propID, Int32 *answer) x; \
+
+
+ARCHIVE_INTERFACE(IArchiveUpdateCallbackArcProp, 0x85)
+{
+ INTERFACE_IArchiveUpdateCallbackArcProp(PURE);
+};
+*/
+
+/*
UpdateItems()
-------------
@@ -636,9 +678,40 @@ 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))
+*/
+
#endif
diff --git a/CPP/7zip/Archive/Icons/7z.ico b/CPP/7zip/Archive/Icons/7z.ico
index 319753a1..319753a1 100644..100755
--- a/CPP/7zip/Archive/Icons/7z.ico
+++ b/CPP/7zip/Archive/Icons/7z.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Icons/apfs.ico b/CPP/7zip/Archive/Icons/apfs.ico
new file mode 100755
index 00000000..124eb76c
--- /dev/null
+++ b/CPP/7zip/Archive/Icons/apfs.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Icons/arj.ico b/CPP/7zip/Archive/Icons/arj.ico
index c0f8b141..c0f8b141 100644..100755
--- a/CPP/7zip/Archive/Icons/arj.ico
+++ b/CPP/7zip/Archive/Icons/arj.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Icons/bz2.ico b/CPP/7zip/Archive/Icons/bz2.ico
index f22abebc..f22abebc 100644..100755
--- a/CPP/7zip/Archive/Icons/bz2.ico
+++ b/CPP/7zip/Archive/Icons/bz2.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Icons/cab.ico b/CPP/7zip/Archive/Icons/cab.ico
index c96c0f01..c96c0f01 100644..100755
--- a/CPP/7zip/Archive/Icons/cab.ico
+++ b/CPP/7zip/Archive/Icons/cab.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Icons/cpio.ico b/CPP/7zip/Archive/Icons/cpio.ico
index 9abaabc7..9abaabc7 100644..100755
--- a/CPP/7zip/Archive/Icons/cpio.ico
+++ b/CPP/7zip/Archive/Icons/cpio.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Icons/deb.ico b/CPP/7zip/Archive/Icons/deb.ico
index 97a08654..97a08654 100644..100755
--- a/CPP/7zip/Archive/Icons/deb.ico
+++ b/CPP/7zip/Archive/Icons/deb.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Icons/dmg.ico b/CPP/7zip/Archive/Icons/dmg.ico
index 7d63b09f..7d63b09f 100644..100755
--- a/CPP/7zip/Archive/Icons/dmg.ico
+++ b/CPP/7zip/Archive/Icons/dmg.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Icons/fat.ico b/CPP/7zip/Archive/Icons/fat.ico
index 7503d933..7503d933 100644..100755
--- a/CPP/7zip/Archive/Icons/fat.ico
+++ b/CPP/7zip/Archive/Icons/fat.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Icons/gz.ico b/CPP/7zip/Archive/Icons/gz.ico
index d402a698..d402a698 100644..100755
--- a/CPP/7zip/Archive/Icons/gz.ico
+++ b/CPP/7zip/Archive/Icons/gz.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Icons/hfs.ico b/CPP/7zip/Archive/Icons/hfs.ico
index bf2c1986..bf2c1986 100644..100755
--- a/CPP/7zip/Archive/Icons/hfs.ico
+++ b/CPP/7zip/Archive/Icons/hfs.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Icons/iso.ico b/CPP/7zip/Archive/Icons/iso.ico
index b3e3ac2f..b3e3ac2f 100644..100755
--- a/CPP/7zip/Archive/Icons/iso.ico
+++ b/CPP/7zip/Archive/Icons/iso.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Icons/lzh.ico b/CPP/7zip/Archive/Icons/lzh.ico
index 84dab49c..84dab49c 100644..100755
--- a/CPP/7zip/Archive/Icons/lzh.ico
+++ b/CPP/7zip/Archive/Icons/lzh.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Icons/lzma.ico b/CPP/7zip/Archive/Icons/lzma.ico
index 2de2c249..2de2c249 100644..100755
--- a/CPP/7zip/Archive/Icons/lzma.ico
+++ b/CPP/7zip/Archive/Icons/lzma.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Icons/ntfs.ico b/CPP/7zip/Archive/Icons/ntfs.ico
index 6b2aeb00..6b2aeb00 100644..100755
--- a/CPP/7zip/Archive/Icons/ntfs.ico
+++ b/CPP/7zip/Archive/Icons/ntfs.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Icons/rar.ico b/CPP/7zip/Archive/Icons/rar.ico
index 2918d294..2918d294 100644..100755
--- a/CPP/7zip/Archive/Icons/rar.ico
+++ b/CPP/7zip/Archive/Icons/rar.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Icons/rpm.ico b/CPP/7zip/Archive/Icons/rpm.ico
index cdeb8d1b..cdeb8d1b 100644..100755
--- a/CPP/7zip/Archive/Icons/rpm.ico
+++ b/CPP/7zip/Archive/Icons/rpm.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Icons/split.ico b/CPP/7zip/Archive/Icons/split.ico
index 65723ff3..65723ff3 100644..100755
--- a/CPP/7zip/Archive/Icons/split.ico
+++ b/CPP/7zip/Archive/Icons/split.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Icons/squashfs.ico b/CPP/7zip/Archive/Icons/squashfs.ico
index b802d942..b802d942 100644..100755
--- a/CPP/7zip/Archive/Icons/squashfs.ico
+++ b/CPP/7zip/Archive/Icons/squashfs.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Icons/tar.ico b/CPP/7zip/Archive/Icons/tar.ico
index 6835885b..6835885b 100644..100755
--- a/CPP/7zip/Archive/Icons/tar.ico
+++ b/CPP/7zip/Archive/Icons/tar.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Icons/vhd.ico b/CPP/7zip/Archive/Icons/vhd.ico
index 33bed3c9..33bed3c9 100644..100755
--- a/CPP/7zip/Archive/Icons/vhd.ico
+++ b/CPP/7zip/Archive/Icons/vhd.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Icons/wim.ico b/CPP/7zip/Archive/Icons/wim.ico
index 887975e6..887975e6 100644..100755
--- a/CPP/7zip/Archive/Icons/wim.ico
+++ b/CPP/7zip/Archive/Icons/wim.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Icons/xar.ico b/CPP/7zip/Archive/Icons/xar.ico
index 281aa7dc..281aa7dc 100644..100755
--- a/CPP/7zip/Archive/Icons/xar.ico
+++ b/CPP/7zip/Archive/Icons/xar.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Icons/xz.ico b/CPP/7zip/Archive/Icons/xz.ico
index bc07a7eb..bc07a7eb 100644..100755
--- a/CPP/7zip/Archive/Icons/xz.ico
+++ b/CPP/7zip/Archive/Icons/xz.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Icons/z.ico b/CPP/7zip/Archive/Icons/z.ico
index 2db53583..2db53583 100644..100755
--- a/CPP/7zip/Archive/Icons/z.ico
+++ b/CPP/7zip/Archive/Icons/z.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Icons/zip.ico b/CPP/7zip/Archive/Icons/zip.ico
index 2af46066..2af46066 100644..100755
--- a/CPP/7zip/Archive/Icons/zip.ico
+++ b/CPP/7zip/Archive/Icons/zip.ico
Binary files differ
diff --git a/CPP/7zip/Archive/IhexHandler.cpp b/CPP/7zip/Archive/IhexHandler.cpp
index 05453ee6..05453ee6 100644..100755
--- a/CPP/7zip/Archive/IhexHandler.cpp
+++ b/CPP/7zip/Archive/IhexHandler.cpp
diff --git a/CPP/7zip/Archive/Iso/IsoHandler.cpp b/CPP/7zip/Archive/Iso/IsoHandler.cpp
index 87f4aa3b..8588a7c5 100644..100755
--- a/CPP/7zip/Archive/Iso/IsoHandler.cpp
+++ b/CPP/7zip/Archive/Iso/IsoHandler.cpp
@@ -6,9 +6,6 @@
#include "../../../Common/MyLinux.h"
#include "../../../Common/StringConvert.h"
-#include "../../../Windows/PropVariant.h"
-#include "../../../Windows/TimeUtils.h"
-
#include "../../Common/LimitedStreams.h"
#include "../../Common/ProgressUtils.h"
@@ -34,8 +31,8 @@ static const Byte kProps[] =
// kpidCTime,
// kpidATime,
kpidPosixAttrib,
- // kpidUser,
- // kpidGroup,
+ // kpidUserId,
+ // kpidGroupId,
// kpidLinks,
kpidSymLink
};
@@ -127,8 +124,8 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
prop = s;
break;
}
- case kpidCTime: { FILETIME utc; if (vol.CTime.GetFileTime(utc)) prop = utc; break; }
- case kpidMTime: { FILETIME utc; if (vol.MTime.GetFileTime(utc)) prop = utc; break; }
+ case kpidCTime: { vol.CTime.GetFileTime(prop); break; }
+ case kpidMTime: { vol.MTime.GetFileTime(prop); break; }
}
}
@@ -242,8 +239,8 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidPosixAttrib:
/*
case kpidLinks:
- case kpidUser:
- case kpidGroup:
+ case kpidUserId:
+ case kpidGroupId:
*/
{
if (_archive.IsSusp)
@@ -254,8 +251,8 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidPosixAttrib: t = k_Px_Mode; break;
/*
case kpidLinks: t = k_Px_Links; break;
- case kpidUser: t = k_Px_User; break;
- case kpidGroup: t = k_Px_Group; break;
+ case kpidUserId: t = k_Px_User; break;
+ case kpidGroupId: t = k_Px_Group; break;
*/
}
UInt32 v;
@@ -276,9 +273,8 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
// case kpidCTime:
// case kpidATime:
{
- FILETIME utc;
- if (/* propID == kpidMTime && */ item.DateTime.GetFileTime(utc))
- prop = utc;
+ // if
+ item.DateTime.GetFileTime(prop);
/*
else
{
diff --git a/CPP/7zip/Archive/Iso/IsoHandler.h b/CPP/7zip/Archive/Iso/IsoHandler.h
index 1923784d..1923784d 100644..100755
--- a/CPP/7zip/Archive/Iso/IsoHandler.h
+++ b/CPP/7zip/Archive/Iso/IsoHandler.h
diff --git a/CPP/7zip/Archive/Iso/IsoHeader.cpp b/CPP/7zip/Archive/Iso/IsoHeader.cpp
index 3b59060a..3b59060a 100644..100755
--- a/CPP/7zip/Archive/Iso/IsoHeader.cpp
+++ b/CPP/7zip/Archive/Iso/IsoHeader.cpp
diff --git a/CPP/7zip/Archive/Iso/IsoHeader.h b/CPP/7zip/Archive/Iso/IsoHeader.h
index e6a4d327..e6a4d327 100644..100755
--- a/CPP/7zip/Archive/Iso/IsoHeader.h
+++ b/CPP/7zip/Archive/Iso/IsoHeader.h
diff --git a/CPP/7zip/Archive/Iso/IsoIn.cpp b/CPP/7zip/Archive/Iso/IsoIn.cpp
index 211b3eea..67802359 100644..100755
--- a/CPP/7zip/Archive/Iso/IsoIn.cpp
+++ b/CPP/7zip/Archive/Iso/IsoIn.cpp
@@ -587,6 +587,8 @@ HRESULT CInArchive::Open2()
for (MainVolDescIndex = VolDescs.Size() - 1; MainVolDescIndex > 0; MainVolDescIndex--)
if (VolDescs[MainVolDescIndex].IsJoliet())
break;
+ /* FIXME: some volume can contain Rock Ridge, that is better than
+ Joliet volume. So we need some way to detect such case */
// MainVolDescIndex = 0; // to read primary volume
const CVolumeDescriptor &vd = VolDescs[MainVolDescIndex];
if (vd.LogicalBlockSize != kBlockSize)
diff --git a/CPP/7zip/Archive/Iso/IsoIn.h b/CPP/7zip/Archive/Iso/IsoIn.h
index 347f9e9b..a705b06a 100644..100755
--- a/CPP/7zip/Archive/Iso/IsoIn.h
+++ b/CPP/7zip/Archive/Iso/IsoIn.h
@@ -127,17 +127,18 @@ struct CDateTime
bool NotSpecified() const { return Year == 0 && Month == 0 && Day == 0 &&
Hour == 0 && Minute == 0 && Second == 0 && GmtOffset == 0; }
- bool GetFileTime(FILETIME &ft) const
+ bool GetFileTime(NWindows::NCOM::CPropVariant &prop) const
{
- UInt64 value;
- bool res = NWindows::NTime::GetSecondsSince1601(Year, Month, Day, Hour, Minute, Second, value);
+ UInt64 v;
+ const bool res = NWindows::NTime::GetSecondsSince1601(Year, Month, Day, Hour, Minute, Second, v);
if (res)
{
- value -= (Int64)((Int32)GmtOffset * 15 * 60);
- value *= 10000000;
+ v -= (Int64)((Int32)GmtOffset * 15 * 60);
+ v *= 10000000;
+ if (Hundredths < 100)
+ v += (UInt32)Hundredths * 100000;
+ prop.SetAsTimeFrom_Ft64_Prec(v, k_PropVar_TimePrec_Base + 2);
}
- ft.dwLowDateTime = (DWORD)value;
- ft.dwHighDateTime = (DWORD)(value >> 32);
return res;
}
};
diff --git a/CPP/7zip/Archive/Iso/IsoItem.h b/CPP/7zip/Archive/Iso/IsoItem.h
index a42ae039..8c2a7253 100644..100755
--- a/CPP/7zip/Archive/Iso/IsoItem.h
+++ b/CPP/7zip/Archive/Iso/IsoItem.h
@@ -25,17 +25,16 @@ struct CRecordingDateTime
Byte Second;
signed char GmtOffset; // min intervals from -48 (West) to +52 (East) recorded.
- bool GetFileTime(FILETIME &ft) const
+ bool GetFileTime(NWindows::NCOM::CPropVariant &prop) const
{
- UInt64 value;
- bool res = NWindows::NTime::GetSecondsSince1601(Year + 1900, Month, Day, Hour, Minute, Second, value);
+ UInt64 v;
+ const bool res = NWindows::NTime::GetSecondsSince1601(Year + 1900, Month, Day, Hour, Minute, Second, v);
if (res)
{
- value -= (Int64)((Int32)GmtOffset * 15 * 60);
- value *= 10000000;
+ v -= (Int64)((Int32)GmtOffset * 15 * 60);
+ v *= 10000000;
+ prop.SetAsTimeFrom_Ft64_Prec(v, k_PropVar_TimePrec_Base);
}
- ft.dwLowDateTime = (DWORD)value;
- ft.dwHighDateTime = (DWORD)(value >> 32);
return res;
}
};
diff --git a/CPP/7zip/Archive/Iso/IsoRegister.cpp b/CPP/7zip/Archive/Iso/IsoRegister.cpp
index 0205238d..0205238d 100644..100755
--- a/CPP/7zip/Archive/Iso/IsoRegister.cpp
+++ b/CPP/7zip/Archive/Iso/IsoRegister.cpp
diff --git a/CPP/7zip/Archive/Iso/StdAfx.h b/CPP/7zip/Archive/Iso/StdAfx.h
index 2854ff3e..2854ff3e 100644..100755
--- a/CPP/7zip/Archive/Iso/StdAfx.h
+++ b/CPP/7zip/Archive/Iso/StdAfx.h
diff --git a/CPP/7zip/Archive/LpHandler.cpp b/CPP/7zip/Archive/LpHandler.cpp
new file mode 100755
index 00000000..b2720f4b
--- /dev/null
+++ b/CPP/7zip/Archive/LpHandler.cpp
@@ -0,0 +1,1173 @@
+// LpHandler.cpp
+
+#include "StdAfx.h"
+
+#include "../../../C/CpuArch.h"
+#include "../../../C/Sha256.h"
+
+#include "../../Common/ComTry.h"
+#include "../../Common/IntToString.h"
+#include "../../Common/MyBuffer.h"
+
+#include "../../Windows/PropVariantUtils.h"
+
+#include "../Common/LimitedStreams.h"
+#include "../Common/ProgressUtils.h"
+#include "../Common/RegisterArc.h"
+#include "../Common/StreamUtils.h"
+
+#include "../Compress/CopyCoder.h"
+
+#define Get16(p) GetUi16(p)
+#define Get32(p) GetUi32(p)
+#define Get64(p) GetUi64(p)
+
+#define G16(_offs_, dest) dest = Get16(p + (_offs_));
+#define G32(_offs_, dest) dest = Get32(p + (_offs_));
+#define G64(_offs_, dest) dest = Get64(p + (_offs_));
+
+using namespace NWindows;
+
+namespace NArchive {
+
+namespace NExt {
+API_FUNC_IsArc IsArc_Ext_PhySize(const Byte *p, size_t size, UInt64 *phySize);
+}
+
+namespace NLp {
+
+/*
+Android 10+ use Android's Dynamic Partitions to allow the
+different read-only system partitions (e.g. system, vendor, product)
+to share the same pool of storage space (as LVM in Linux).
+Name for partition: "super" (for GPT) or "super.img" (for file).
+Dynamic Partition Tools: lpmake
+All partitions that are A/B-ed should be named as follows (slots are always named a, b, etc.):
+boot_a, boot_b, system_a, system_b, vendor_a, vendor_b.
+*/
+
+#define LP_METADATA_MAJOR_VERSION 10
+// #define LP_METADATA_MINOR_VERSION_MIN 0
+// #define LP_METADATA_MINOR_VERSION_MAX 2
+
+// #define LP_SECTOR_SIZE 512
+static const unsigned kSectorSizeLog = 9;
+
+/* Amount of space reserved at the start of every super partition to avoid
+ * creating an accidental boot sector. */
+#define LP_PARTITION_RESERVED_BYTES 4096
+#define LP_METADATA_GEOMETRY_SIZE 4096
+#define LP_METADATA_HEADER_MAGIC 0x414C5030
+
+#define SIGNATURE { 0x67, 0x44, 0x6c, 0x61, 0x34, 0, 0, 0 }
+static const unsigned k_SignatureSize = 8;
+static const Byte k_Signature[k_SignatureSize] = SIGNATURE;
+
+// The length (36) is the same as the maximum length of a GPT partition name.
+static const unsigned kNameLen = 36;
+
+static void AddName36ToString(AString &s, const char *name, bool strictConvert)
+{
+ for (unsigned i = 0; i < kNameLen; i++)
+ {
+ char c = name[i];
+ if (c == 0)
+ return;
+ if (strictConvert && c < 32)
+ c = '_';
+ s += c;
+ }
+}
+
+
+static const unsigned k_Geometry_Size = 0x34;
+
+// LpMetadataGeometry
+struct CGeometry
+{
+ // UInt32 magic;
+ // UInt32 struct_size;
+ // Byte checksum[32]; /* SHA256 checksum of this struct, with this field set to 0. */
+
+ /* Maximum amount of space a single copy of the metadata can use,
+ a multiple of LP_SECTOR_SIZE. */
+ UInt32 metadata_max_size;
+
+ /* Number of copies of the metadata to keep.
+ For Non-A/B: 1, For A/B: 2, for A/B/C: 3.
+ A backup copy of each slot is kept */
+ UInt32 metadata_slot_count;
+
+ /* minimal alignment for partition and extent sizes, a multiple of LP_SECTOR_SIZE. */
+ UInt32 logical_block_size;
+
+ bool Parse(const Byte *p)
+ {
+ G32 (40, metadata_max_size);
+ G32 (44, metadata_slot_count);
+ G32 (48, logical_block_size);
+ if (metadata_slot_count == 0 || metadata_slot_count >= ((UInt32)1 << 20))
+ return false;
+ if (metadata_max_size == 0)
+ return false;
+ if ((metadata_max_size & (((UInt32)1 << kSectorSizeLog) - 1)) != 0)
+ return false;
+ return true;
+ }
+
+ UInt64 GetTotalMetadataSize() const
+ {
+ // there are 2 copies of GEOMETRY and METADATA slots
+ return LP_PARTITION_RESERVED_BYTES +
+ LP_METADATA_GEOMETRY_SIZE * 2 +
+ ((UInt64)metadata_max_size * metadata_slot_count) * 2;
+ }
+};
+
+
+
+// LpMetadataTableDescriptor
+struct CDescriptor
+{
+ UInt32 offset; /* Location of the table, relative to end of the metadata header. */
+ UInt32 num_entries; /* Number of entries in the table. */
+ UInt32 entry_size; /* Size of each entry in the table, in bytes. */
+
+ void Parse(const Byte *p)
+ {
+ G32 (0, offset);
+ G32 (4, num_entries);
+ G32 (8, entry_size);
+ }
+
+ bool CheckLimits(UInt32 limit) const
+ {
+ if (entry_size == 0)
+ return false;
+ const UInt32 size = num_entries * entry_size;
+ if (size / entry_size != num_entries)
+ return false;
+ if (offset > limit || limit - offset < size)
+ return false;
+ return true;
+ }
+};
+
+
+// #define LP_PARTITION_ATTR_NONE 0x0
+// #define LP_PARTITION_ATTR_READONLY (1 << 0)
+
+/* This flag is only intended to be used with super_empty.img and super.img on
+ * retrofit devices. On these devices there are A and B super partitions, and
+ * we don't know ahead of time which slot the image will be applied to.
+ *
+ * If set, the partition name needs a slot suffix applied. The slot suffix is
+ * determined by the metadata slot number (0 = _a, 1 = _b).
+ */
+// #define LP_PARTITION_ATTR_SLOT_SUFFIXED (1 << 1)
+
+/* This flag is applied automatically when using MetadataBuilder::NewForUpdate.
+ * It signals that the partition was created (or modified) for a snapshot-based
+ * update. If this flag is not present, the partition was likely flashed via
+ * fastboot.
+ */
+// #define LP_PARTITION_ATTR_UPDATED (1 << 2)
+
+/* This flag marks a partition as disabled. It should not be used or mapped. */
+// #define LP_PARTITION_ATTR_DISABLED (1 << 3)
+
+static const char * const g_PartitionAttr[] =
+{
+ "READONLY"
+ , "SLOT_SUFFIXED"
+ , "UPDATED"
+ , "DISABLED"
+};
+
+static unsigned const k_MetaPartition_Size = 52;
+
+// LpMetadataPartition
+struct CPartition
+{
+ /* ASCII characters: alphanumeric or _. at least one ASCII character,
+ (name) must be unique across all partition names. */
+ char name[kNameLen];
+
+ UInt32 attributes; /* (LP_PARTITION_ATTR_*). */
+
+ /* Index of the first extent owned by this partition. The extent will
+ * start at logical sector 0. Gaps between extents are not allowed. */
+ UInt32 first_extent_index;
+
+ /* Number of extents in the partition. Every partition must have at least one extent. */
+ UInt32 num_extents;
+
+ /* Group this partition belongs to. */
+ UInt32 group_index;
+
+ void Parse(const Byte *p)
+ {
+ memcpy(name, p, kNameLen);
+ G32 (36, attributes);
+ G32 (40, first_extent_index);
+ G32 (44, num_extents);
+ G32 (48, group_index);
+ }
+
+ // calced properties:
+ UInt32 MethodsMask;
+ UInt64 NumSectors;
+ UInt64 NumSectors_Pack;
+ const char *Ext;
+
+ UInt64 GetSize() const { return NumSectors << kSectorSizeLog; }
+ UInt64 GetPackSize() const { return NumSectors_Pack << kSectorSizeLog; }
+
+ CPartition():
+ MethodsMask(0),
+ NumSectors(0),
+ NumSectors_Pack(0),
+ Ext(NULL)
+ {}
+};
+
+
+
+
+#define LP_TARGET_TYPE_LINEAR 0
+/* This extent is a dm-zero target. The index is ignored and must be 0. */
+#define LP_TARGET_TYPE_ZERO 1
+
+static const char * const g_Methods[] =
+{
+ "RAW" // "LINEAR"
+ , "ZERO"
+};
+
+static unsigned const k_MetaExtent_Size = 24;
+
+// LpMetadataExtent
+struct CExtent
+{
+ UInt64 num_sectors; /* Length in 512-byte sectors. */
+ UInt32 target_type; /* Target type for device-mapper (LP_TARGET_TYPE_*). */
+
+ /* for LINEAR: The sector on the physical partition that this extent maps onto.
+ for ZERO: must be 0. */
+ UInt64 target_data;
+
+ /* for LINEAR: index into the block devices table.
+ for ZERO: must be 0. */
+ UInt32 target_source;
+
+ bool IsRAW() const { return target_type == LP_TARGET_TYPE_LINEAR; }
+
+ void Parse(const Byte *p)
+ {
+ G64 (0, num_sectors);
+ G32 (8, target_type);
+ G64 (12, target_data);
+ G32 (20, target_source);
+ }
+};
+
+
+/* This flag is only intended to be used with super_empty.img and super.img on
+ * retrofit devices. If set, the group needs a slot suffix to be interpreted
+ * correctly. The suffix is automatically applied by ReadMetadata().
+ */
+// #define LP_GROUP_SLOT_SUFFIXED (1 << 0)
+static unsigned const k_Group_Size = 48;
+
+// LpMetadataPartitionGroup
+struct CGroup
+{
+ char name[kNameLen];
+ UInt32 flags; /* (LP_GROUP_*). */
+ UInt64 maximum_size; /* Maximum size in bytes. If 0, the group has no maximum size. */
+
+ void Parse(const Byte *p)
+ {
+ memcpy(name, p, kNameLen);
+ G32 (36, flags);
+ G64 (40, maximum_size);
+ }
+};
+
+
+
+
+/* This flag is only intended to be used with super_empty.img and super.img on
+ * retrofit devices. On these devices there are A and B super partitions, and
+ * we don't know ahead of time which slot the image will be applied to.
+ *
+ * If set, the block device needs a slot suffix applied before being used with
+ * IPartitionOpener. The slot suffix is determined by the metadata slot number
+ * (0 = _a, 1 = _b).
+ */
+// #define LP_BLOCK_DEVICE_SLOT_SUFFIXED (1 << 0)
+
+static unsigned const k_Device_Size = 64;
+
+/* This struct defines an entry in the block_devices table. There must be at
+ * least one device, and the first device must represent the partition holding
+ * the super metadata.
+ */
+// LpMetadataBlockDevice
+struct CDevice
+{
+ /* 0: First usable sector for allocating logical partitions. this will be
+ * the first sector after the initial geometry blocks, followed by the
+ * space consumed by metadata_max_size*metadata_slot_count*2.
+ */
+ UInt64 first_logical_sector;
+
+ /* 8: Alignment for defining partitions or partition extents. For example,
+ * an alignment of 1MiB will require that all partitions have a size evenly
+ * divisible by 1MiB, and that the smallest unit the partition can grow by
+ * is 1MiB.
+ *
+ * Alignment is normally determined at runtime when growing or adding
+ * partitions. If for some reason the alignment cannot be determined, then
+ * this predefined alignment in the geometry is used instead. By default
+ * it is set to 1MiB.
+ */
+ UInt32 alignment;
+
+ /* 12: Alignment offset for "stacked" devices. For example, if the "super"
+ * partition itself is not aligned within the parent block device's
+ * partition table, then we adjust for this in deciding where to place
+ * |first_logical_sector|.
+ *
+ * Similar to |alignment|, this will be derived from the operating system.
+ * If it cannot be determined, it is assumed to be 0.
+ */
+ UInt32 alignment_offset;
+
+ /* 16: Block device size, as specified when the metadata was created. This
+ * can be used to verify the geometry against a target device.
+ */
+ UInt64 size;
+
+ /* 24: Partition name in the GPT*/
+ char partition_name[kNameLen];
+
+ /* 60: Flags (see LP_BLOCK_DEVICE_* flags below). */
+ UInt32 flags;
+
+ void Parse(const Byte *p)
+ {
+ memcpy(partition_name, p + 24, kNameLen);
+ G64 (0, first_logical_sector);
+ G32 (8, alignment);
+ G32 (12, alignment_offset);
+ G64 (16, size);
+ G32 (60, flags);
+ }
+};
+
+
+/* This device uses Virtual A/B. Note that on retrofit devices, the expanded
+ * header may not be present.
+ */
+// #define LP_HEADER_FLAG_VIRTUAL_AB_DEVICE 0x1
+
+static const char * const g_Header_Flags[] =
+{
+ "VIRTUAL_AB"
+};
+
+
+static const unsigned k_LpMetadataHeader10_size = 128;
+static const unsigned k_LpMetadataHeader12_size = 256;
+
+struct LpMetadataHeader
+{
+ /* 0: Four bytes equal to LP_METADATA_HEADER_MAGIC. */
+ UInt32 magic;
+
+ /* 4: Version number required to read this metadata. If the version is not
+ * equal to the library version, the metadata should be considered
+ * incompatible.
+ */
+ UInt16 major_version;
+
+ /* 6: Minor version. A library supporting newer features should be able to
+ * read metadata with an older minor version. However, an older library
+ * should not support reading metadata if its minor version is higher.
+ */
+ UInt16 minor_version;
+
+ /* 8: The size of this header struct. */
+ UInt32 header_size;
+
+ /* 12: SHA256 checksum of the header, up to |header_size| bytes, computed as
+ * if this field were set to 0.
+ */
+ // Byte header_checksum[32];
+
+ /* 44: The total size of all tables. This size is contiguous; tables may not
+ * have gaps in between, and they immediately follow the header.
+ */
+ UInt32 tables_size;
+
+ /* 48: SHA256 checksum of all table contents. */
+ Byte tables_checksum[32];
+
+ /* 80: Partition table descriptor. */
+ CDescriptor partitions;
+ /* 92: Extent table descriptor. */
+ CDescriptor extents;
+ /* 104: Updateable group descriptor. */
+ CDescriptor groups;
+ /* 116: Block device table. */
+ CDescriptor block_devices;
+
+ /* Everything past here is header version 1.2+, and is only included if
+ * needed. When liblp supporting >= 1.2 reads a < 1.2 header, it must
+ * zero these additional fields.
+ */
+
+ /* 128: See LP_HEADER_FLAG_ constants for possible values. Header flags are
+ * independent of the version number and intended to be informational only.
+ * New flags can be added without bumping the version.
+ */
+ // UInt32 flags;
+
+ /* 132: Reserved (zero), pad to 256 bytes. */
+ // Byte reserved[124];
+
+ void Parse128(const Byte *p)
+ {
+ G32 (0, magic);
+ G16 (4, major_version);
+ G16 (6, minor_version);
+ G32 (8, header_size)
+ // Byte header_checksum[32];
+ G32 (44, tables_size)
+ memcpy (tables_checksum, p + 48, 32);
+ partitions.Parse(p + 80);
+ extents.Parse(p + 92);
+ groups.Parse(p + 104);
+ block_devices.Parse(p + 116);
+ /* Everything past here is header version 1.2+, and is only included if
+ * needed. When liblp supporting >= 1.2 reads a < 1.2 header, it must
+ * zero these additional fields.
+ */
+ }
+};
+
+
+static bool CheckSha256(const Byte *data, size_t size, const Byte *checksum)
+{
+ CSha256 sha;
+ Sha256_Init(&sha);
+ Sha256_Update(&sha, data, size);
+ Byte calced[32];
+ Sha256_Final(&sha, calced);
+ return memcmp(checksum, calced, 32) == 0;
+}
+
+static bool CheckSha256_csOffset(Byte *data, size_t size, unsigned hashOffset)
+{
+ Byte checksum[32];
+ Byte *shaData = &data[hashOffset];
+ memcpy(checksum, shaData, 32);
+ memset(shaData, 0, 32);
+ return CheckSha256(data, size, checksum);
+}
+
+
+
+class CHandler:
+ public IInArchive,
+ public IInArchiveGetStream,
+ public CMyUnknownImp
+{
+ CRecordVector<CPartition> _items;
+ CRecordVector<CExtent> Extents;
+
+ CMyComPtr<IInStream> _stream;
+ UInt64 _totalSize;
+ // UInt64 _usedSize;
+ // UInt64 _headersSize;
+
+ CGeometry geom;
+ UInt16 Major_version;
+ UInt16 Minor_version;
+ UInt32 Flags;
+
+ Int32 _mainFileIndex;
+ UInt32 MethodsMask;
+ bool _headerWarning;
+ AString GroupsString;
+ AString DevicesString;
+ AString DeviceArcName;
+
+ HRESULT Open2(IInStream *stream);
+
+public:
+ MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream)
+ INTERFACE_IInArchive(;)
+ STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
+};
+
+
+static void AddComment_UInt64(AString &s, const char *name, UInt64 val)
+{
+ s.Add_Space();
+ s += name;
+ s += '=';
+ s.Add_UInt64(val);
+}
+
+
+static bool IsBufZero(const Byte *data, size_t size)
+{
+ for (size_t i = 0; i < size; i += 4)
+ if (*(const UInt32 *)(const void *)(data + i) != 0)
+ return false;
+ return true;
+}
+
+
+HRESULT CHandler::Open2(IInStream *stream)
+{
+ RINOK(stream->Seek(LP_PARTITION_RESERVED_BYTES, STREAM_SEEK_SET, NULL));
+ {
+ Byte buf[k_Geometry_Size];
+ RINOK(ReadStream_FALSE(stream, buf, k_Geometry_Size));
+ if (memcmp(buf, k_Signature, k_SignatureSize) != 0)
+ return S_FALSE;
+ if (!geom.Parse(buf))
+ return S_FALSE;
+ if (!CheckSha256_csOffset(buf, k_Geometry_Size, 8))
+ return S_FALSE;
+ }
+
+ CByteBuffer buffer;
+ RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));
+ buffer.Alloc(LP_METADATA_GEOMETRY_SIZE * 2);
+ {
+ // buffer.Size() >= LP_PARTITION_RESERVED_BYTES
+ RINOK(ReadStream_FALSE(stream, buffer, LP_PARTITION_RESERVED_BYTES));
+ if (!IsBufZero(buffer, LP_PARTITION_RESERVED_BYTES))
+ {
+ _headerWarning = true;
+ // return S_FALSE;
+ }
+ }
+
+ RINOK(ReadStream_FALSE(stream, buffer, LP_METADATA_GEOMETRY_SIZE * 2));
+ // we check that 2 copies of GEOMETRY are identical:
+ if (memcmp(buffer, buffer + LP_METADATA_GEOMETRY_SIZE, LP_METADATA_GEOMETRY_SIZE) != 0
+ || !IsBufZero(buffer + k_Geometry_Size, LP_METADATA_GEOMETRY_SIZE - k_Geometry_Size))
+ {
+ _headerWarning = true;
+ // return S_FALSE;
+ }
+
+ RINOK(ReadStream_FALSE(stream, buffer, k_LpMetadataHeader10_size));
+ LpMetadataHeader header;
+ header.Parse128(buffer);
+ if (header.magic != LP_METADATA_HEADER_MAGIC ||
+ header.major_version != LP_METADATA_MAJOR_VERSION ||
+ header.header_size < k_LpMetadataHeader10_size)
+ return S_FALSE;
+ Flags = 0;
+ if (header.header_size > k_LpMetadataHeader10_size)
+ {
+ if (header.header_size != k_LpMetadataHeader12_size)
+ return S_FALSE;
+ RINOK(ReadStream_FALSE(stream, buffer + k_LpMetadataHeader10_size,
+ header.header_size - k_LpMetadataHeader10_size));
+ Flags = Get32(buffer + k_LpMetadataHeader10_size);
+ }
+ Major_version = header.major_version;
+ Minor_version = header.minor_version;
+
+ if (!CheckSha256_csOffset(buffer, header.header_size, 12))
+ return S_FALSE;
+
+ if (geom.metadata_max_size < header.tables_size ||
+ geom.metadata_max_size - header.tables_size < header.header_size)
+ return S_FALSE;
+
+ buffer.AllocAtLeast(header.tables_size);
+ RINOK(ReadStream_FALSE(stream, buffer, header.tables_size));
+
+ const UInt64 totalMetaSize = geom.GetTotalMetadataSize();
+ // _headersSize = _totalSize;
+ _totalSize = totalMetaSize;
+
+ if (!CheckSha256(buffer, header.tables_size, header.tables_checksum))
+ return S_FALSE;
+
+ {
+ const CDescriptor &d = header.partitions;
+ if (!d.CheckLimits(header.tables_size))
+ return S_FALSE;
+ if (d.entry_size != k_MetaPartition_Size)
+ return S_FALSE;
+ for (UInt32 i = 0; i < d.num_entries; i++)
+ {
+ CPartition part;
+ part.Parse(buffer + d.offset + i * d.entry_size);
+ const UInt32 extLimit = part.first_extent_index + part.num_extents;
+ if (extLimit < part.first_extent_index ||
+ extLimit > header.extents.num_entries ||
+ part.group_index >= header.groups.num_entries)
+ return S_FALSE;
+ _items.Add(part);
+ }
+ }
+ {
+ const CDescriptor &d = header.extents;
+ if (!d.CheckLimits(header.tables_size))
+ return S_FALSE;
+ if (d.entry_size != k_MetaExtent_Size)
+ return S_FALSE;
+ for (UInt32 i = 0; i < d.num_entries; i++)
+ {
+ CExtent e;
+ e.Parse(buffer + d.offset + i * d.entry_size);
+ // if (e.target_type > LP_TARGET_TYPE_ZERO) return S_FALSE;
+ if (e.IsRAW())
+ {
+ if (e.target_source >= header.block_devices.num_entries)
+ return S_FALSE;
+ const UInt64 endSector = e.target_data + e.num_sectors;
+ const UInt64 endOffset = endSector << kSectorSizeLog;
+ if (_totalSize < endOffset)
+ _totalSize = endOffset;
+ }
+ MethodsMask |= (UInt32)1 << e.target_type;
+ Extents.Add(e);
+ }
+ }
+
+ // _usedSize = _totalSize;
+ {
+ const CDescriptor &d = header.groups;
+ if (!d.CheckLimits(header.tables_size))
+ return S_FALSE;
+ if (d.entry_size != k_Group_Size)
+ return S_FALSE;
+ AString s;
+ for (UInt32 i = 0; i < d.num_entries; i++)
+ {
+ CGroup g;
+ g.Parse(buffer + d.offset + i * d.entry_size);
+ if (_totalSize < g.maximum_size)
+ _totalSize = g.maximum_size;
+ s += " ";
+ AddName36ToString(s, g.name, true);
+ AddComment_UInt64(s, "maximum_size", g.maximum_size);
+ AddComment_UInt64(s, "flags", g.flags);
+ s.Add_LF();
+ }
+ GroupsString = s;
+ }
+
+ {
+ const CDescriptor &d = header.block_devices;
+ if (!d.CheckLimits(header.tables_size))
+ return S_FALSE;
+ if (d.entry_size != k_Device_Size)
+ return S_FALSE;
+ AString s;
+ // CRecordVector<CDevice> devices;
+ for (UInt32 i = 0; i < d.num_entries; i++)
+ {
+ CDevice v;
+ v.Parse(buffer + d.offset + i * d.entry_size);
+ // if (i == 0)
+ {
+ // it's super_device is first device;
+ if (totalMetaSize > (v.first_logical_sector << kSectorSizeLog))
+ return S_FALSE;
+ }
+ if (_totalSize < v.size)
+ _totalSize = v.size;
+ s += " ";
+ if (i == 0)
+ AddName36ToString(DeviceArcName, v.partition_name, true);
+ // devices.Add(v);
+ AddName36ToString(s, v.partition_name, true);
+ AddComment_UInt64(s, "size", v.size);
+ AddComment_UInt64(s, "first_logical_sector", v.first_logical_sector);
+ AddComment_UInt64(s, "alignment", v.alignment);
+ AddComment_UInt64(s, "alignment_offset", v.alignment_offset);
+ AddComment_UInt64(s, "flags", v.flags);
+ s.Add_LF();
+ }
+ DevicesString = s;
+ }
+
+ {
+ FOR_VECTOR (i, _items)
+ {
+ CPartition &part = _items[i];
+ if (part.first_extent_index > Extents.Size() ||
+ part.num_extents > Extents.Size() - part.first_extent_index)
+ return S_FALSE;
+
+ UInt64 numSectors = 0;
+ UInt64 numSectors_Pack = 0;
+ UInt32 methods = 0;
+ for (UInt32 k = 0; k < part.num_extents; k++)
+ {
+ const CExtent &e = Extents[part.first_extent_index + k];
+ numSectors += e.num_sectors;
+ if (e.IsRAW())
+ numSectors_Pack += e.num_sectors;
+ methods |= (UInt32)1 << e.target_type;
+ }
+ part.NumSectors = numSectors;
+ part.NumSectors_Pack = numSectors_Pack;
+ part.MethodsMask = methods;
+ }
+ }
+
+ return S_OK;
+}
+
+
+STDMETHODIMP CHandler::Open(IInStream *stream,
+ const UInt64 * /* maxCheckStartPosition */,
+ IArchiveOpenCallback * /* openArchiveCallback */)
+{
+ COM_TRY_BEGIN
+ Close();
+ RINOK(Open2(stream));
+ _stream = stream;
+
+ int mainFileIndex = -1;
+ unsigned numNonEmptyParts = 0;
+
+ FOR_VECTOR (fileIndex, _items)
+ {
+ CPartition &item = _items[fileIndex];
+ if (item.NumSectors != 0)
+ {
+ mainFileIndex = fileIndex;
+ numNonEmptyParts++;
+ CMyComPtr<ISequentialInStream> parseStream;
+ if (GetStream(fileIndex, &parseStream) == S_OK && parseStream)
+ {
+ const size_t kParseSize = 1 << 11;
+ Byte buf[kParseSize];
+ if (ReadStream_FAIL(parseStream, buf, kParseSize) == S_OK)
+ {
+ UInt64 extSize;
+ if (NExt::IsArc_Ext_PhySize(buf, kParseSize, &extSize) == k_IsArc_Res_YES)
+ if (extSize == item.GetSize())
+ item.Ext = "ext";
+ }
+ }
+ }
+ }
+ if (numNonEmptyParts == 1)
+ _mainFileIndex = mainFileIndex;
+
+ return S_OK;
+ COM_TRY_END
+}
+
+
+STDMETHODIMP CHandler::Close()
+{
+ _totalSize = 0;
+ // _usedSize = 0;
+ // _headersSize = 0;
+ _items.Clear();
+ Extents.Clear();
+ _stream.Release();
+ _mainFileIndex = -1;
+ _headerWarning = false;
+ MethodsMask = 0;
+ GroupsString.Empty();
+ DevicesString.Empty();
+ DeviceArcName.Empty();
+ return S_OK;
+}
+
+
+static const Byte kProps[] =
+{
+ kpidPath,
+ kpidSize,
+ kpidPackSize,
+ kpidCharacts,
+ kpidMethod,
+ kpidNumBlocks,
+ kpidOffset
+};
+
+static const Byte kArcProps[] =
+{
+ kpidUnpackVer,
+ kpidMethod,
+ kpidClusterSize,
+ // kpidHeadersSize,
+ // kpidFreeSpace,
+ kpidName,
+ kpidComment
+};
+
+IMP_IInArchive_Props
+IMP_IInArchive_ArcProps
+
+STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NCOM::CPropVariant prop;
+ switch (propID)
+ {
+ case kpidMainSubfile:
+ {
+ if (_mainFileIndex >= 0)
+ prop = (UInt32)_mainFileIndex;
+ break;
+ }
+ case kpidPhySize: prop = _totalSize; break;
+
+ // case kpidFreeSpace: if (_usedSize != 0) prop = _totalSize - _usedSize; break;
+ // case kpidHeadersSize: prop = _headersSize; break;
+
+ case kpidMethod:
+ {
+ const UInt32 m = MethodsMask;
+ if (m != 0)
+ {
+ FLAGS_TO_PROP(g_Methods, m, prop);
+ }
+ break;
+ }
+
+ case kpidUnpackVer:
+ {
+ AString s;
+ s.Add_UInt32(Major_version);
+ s += '.';
+ s.Add_UInt32(Minor_version);
+ prop = s;
+ break;
+ }
+
+ case kpidClusterSize:
+ prop = geom.logical_block_size;
+ break;
+
+ case kpidComment:
+ {
+ AString s;
+
+ s += "metadata_slot_count: ";
+ s.Add_UInt32(geom.metadata_slot_count);
+ s.Add_LF();
+
+ s += "metadata_max_size: ";
+ s.Add_UInt32(geom.metadata_max_size);
+ s.Add_LF();
+
+ if (Flags != 0)
+ {
+ s += "flags: ";
+ s += FlagsToString(g_Header_Flags, ARRAY_SIZE(g_Header_Flags), Flags);
+ s.Add_LF();
+ }
+
+ if (!GroupsString.IsEmpty())
+ {
+ s += "Groups:";
+ s.Add_LF();
+ s += GroupsString;
+ }
+
+ if (!DevicesString.IsEmpty())
+ {
+ s += "BlockDevices:";
+ s.Add_LF();
+ s += DevicesString;
+ }
+
+ if (!s.IsEmpty())
+ prop = s;
+ break;
+ }
+
+ case kpidName:
+ if (!DeviceArcName.IsEmpty())
+ prop = DeviceArcName + ".lpimg";
+ break;
+
+ case kpidWarningFlags:
+ if (_headerWarning)
+ {
+ UInt32 v = kpv_ErrorFlags_HeadersError;
+ prop = v;
+ }
+ break;
+ }
+ prop.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+
+STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
+{
+ *numItems = _items.Size();
+ return S_OK;
+}
+
+
+STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NCOM::CPropVariant prop;
+
+ const CPartition &item = _items[index];
+
+ switch (propID)
+ {
+ case kpidPath:
+ {
+ AString s;
+ AddName36ToString(s, item.name, false);
+ if (s.IsEmpty())
+ s.Add_UInt32(index);
+ if (item.num_extents != 0)
+ {
+ s += '.';
+ s += (item.Ext ? item.Ext : "img");
+ }
+ prop = s;
+ break;
+ }
+
+ case kpidSize: prop = item.GetSize(); break;
+ case kpidPackSize: prop = item.GetPackSize(); break;
+ case kpidNumBlocks: prop = item.num_extents; break;
+ case kpidMethod:
+ {
+ const UInt32 m = item.MethodsMask;
+ if (m != 0)
+ {
+ FLAGS_TO_PROP(g_Methods, m, prop);
+ }
+ break;
+ }
+ case kpidOffset:
+ if (item.num_extents != 0)
+ if (item.first_extent_index < Extents.Size())
+ prop = Extents[item.first_extent_index].target_data << kSectorSizeLog;
+ break;
+
+ case kpidCharacts:
+ {
+ AString s;
+ s += "group:";
+ s.Add_UInt32(item.group_index);
+ s.Add_Space();
+ s += FlagsToString(g_PartitionAttr, ARRAY_SIZE(g_PartitionAttr), item.attributes);
+ prop = s;
+ break;
+ }
+ }
+
+ prop.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+
+
+STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
+{
+ COM_TRY_BEGIN
+ *stream = NULL;
+
+ const CPartition &item = _items[index];
+
+ if (item.first_extent_index > Extents.Size()
+ || item.num_extents > Extents.Size() - item.first_extent_index)
+ return S_FALSE;
+
+ if (item.num_extents == 0)
+ return CreateLimitedInStream(_stream, 0, 0, stream);
+
+ if (item.num_extents == 1)
+ {
+ const CExtent &e = Extents[item.first_extent_index];
+ if (e.IsRAW())
+ {
+ const UInt64 pos = e.target_data << kSectorSizeLog;
+ if ((pos >> kSectorSizeLog) != e.target_data)
+ return S_FALSE;
+ const UInt64 size = item.GetSize();
+ if (pos + size < pos)
+ return S_FALSE;
+ return CreateLimitedInStream(_stream, pos, size, stream);
+ }
+ }
+
+ CExtentsStream *extentStreamSpec = new CExtentsStream();
+ CMyComPtr<ISequentialInStream> extentStream = extentStreamSpec;
+
+ // const unsigned kNumDebugExtents = 10;
+ extentStreamSpec->Extents.Reserve(item.num_extents + 1
+ // + kNumDebugExtents
+ );
+
+ UInt64 virt = 0;
+ for (UInt32 k = 0; k < item.num_extents; k++)
+ {
+ const CExtent &e = Extents[item.first_extent_index + k];
+
+ CSeekExtent se;
+ {
+ const UInt64 numSectors = e.num_sectors;
+ if (numSectors == 0)
+ {
+ continue;
+ // return S_FALSE;
+ }
+ const UInt64 numBytes = numSectors << kSectorSizeLog;
+ if ((numBytes >> kSectorSizeLog) != numSectors)
+ return S_FALSE;
+ if (numBytes >= ((UInt64)1 << 63) - virt)
+ return S_FALSE;
+
+ se.Virt = virt;
+ virt += numBytes;
+ }
+
+ const UInt64 phySector = e.target_data;
+ if (e.target_type == LP_TARGET_TYPE_ZERO)
+ {
+ if (phySector != 0)
+ return S_FALSE;
+ se.SetAs_ZeroFill();
+ }
+ else if (e.target_type == LP_TARGET_TYPE_LINEAR)
+ {
+ se.Phy = phySector << kSectorSizeLog;
+ if ((se.Phy >> kSectorSizeLog) != phySector)
+ return S_FALSE;
+ if (se.Phy >= ((UInt64)1 << 63))
+ return S_FALSE;
+ }
+ else
+ return S_FALSE;
+
+ extentStreamSpec->Extents.AddInReserved(se);
+
+ /*
+ {
+ // for debug
+ const UInt64 kAdd = (e.num_sectors << kSectorSizeLog) / kNumDebugExtents;
+ for (unsigned i = 0; i < kNumDebugExtents; i++)
+ {
+ se.Phy += kAdd;
+ // se.Phy += (UInt64)1 << 63; // for debug
+ // se.Phy += 1; // for debug
+ se.Virt += kAdd;
+ extentStreamSpec->Extents.AddInReserved(se);
+ }
+ }
+ */
+ }
+
+ CSeekExtent se;
+ se.Phy = 0;
+ se.Virt = virt;
+ extentStreamSpec->Extents.Add(se);
+ extentStreamSpec->Stream = _stream;
+ extentStreamSpec->Init();
+ *stream = extentStream.Detach();
+
+ return S_OK;
+ COM_TRY_END
+}
+
+
+STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
+ Int32 testMode, IArchiveExtractCallback *extractCallback)
+{
+ COM_TRY_BEGIN
+ const bool allFilesMode = (numItems == (UInt32)(Int32)-1);
+ if (allFilesMode)
+ numItems = _items.Size();
+ if (numItems == 0)
+ return S_OK;
+ UInt64 totalSize = 0;
+ UInt32 i;
+ for (i = 0; i < numItems; i++)
+ {
+ const UInt32 index = allFilesMode ? i : indices[i];
+ totalSize += _items[index].GetSize();
+ }
+ extractCallback->SetTotal(totalSize);
+
+ totalSize = 0;
+
+ NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
+ CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
+
+ CLocalProgress *lps = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> progress = lps;
+ lps->Init(extractCallback, false);
+
+ for (i = 0; i < numItems; i++)
+ {
+ lps->InSize = totalSize;
+ lps->OutSize = totalSize;
+ RINOK(lps->SetCur());
+ CMyComPtr<ISequentialOutStream> outStream;
+ const Int32 askMode = testMode ?
+ NExtract::NAskMode::kTest :
+ NExtract::NAskMode::kExtract;
+ const UInt32 index = allFilesMode ? i : indices[i];
+
+ RINOK(extractCallback->GetStream(index, &outStream, askMode));
+
+ const UInt64 size = _items[index].GetSize();
+ totalSize += size;
+ if (!testMode && !outStream)
+ continue;
+
+ RINOK(extractCallback->PrepareOperation(askMode));
+
+ CMyComPtr<ISequentialInStream> inStream;
+ const HRESULT hres = GetStream(index, &inStream);
+ int opRes = NExtract::NOperationResult::kUnsupportedMethod;
+ if (hres != S_FALSE)
+ {
+ if (hres != S_OK)
+ return hres;
+ RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));
+ opRes = NExtract::NOperationResult::kDataError;
+ if (copyCoderSpec->TotalSize == size)
+ opRes = NExtract::NOperationResult::kOK;
+ else if (copyCoderSpec->TotalSize < size)
+ opRes = NExtract::NOperationResult::kUnexpectedEnd;
+ }
+ outStream.Release();
+ RINOK(extractCallback->SetOperationResult(opRes));
+ }
+
+ return S_OK;
+ COM_TRY_END
+}
+
+
+REGISTER_ARC_I(
+ "LP", "lpimg img", NULL, 0xc1,
+ k_Signature,
+ LP_PARTITION_RESERVED_BYTES,
+ 0,
+ NULL)
+
+}}
diff --git a/CPP/7zip/Archive/LzhHandler.cpp b/CPP/7zip/Archive/LzhHandler.cpp
index e1984d28..6711da60 100644..100755
--- a/CPP/7zip/Archive/LzhHandler.cpp
+++ b/CPP/7zip/Archive/LzhHandler.cpp
@@ -487,22 +487,11 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidHostOS: PAIR_TO_PROP(g_OsPairs, item.OsId, prop); break;
case kpidMTime:
{
- FILETIME utc;
UInt32 unixTime;
if (item.GetUnixTime(unixTime))
- NTime::UnixTimeToFileTime(unixTime, utc);
+ PropVariant_SetFrom_UnixTime(prop, unixTime);
else
- {
- FILETIME localFileTime;
- if (DosTimeToFileTime(item.ModifiedTime, localFileTime))
- {
- if (!LocalFileTimeToFileTime(&localFileTime, &utc))
- utc.dwHighDateTime = utc.dwLowDateTime = 0;
- }
- else
- utc.dwHighDateTime = utc.dwLowDateTime = 0;
- }
- prop = utc;
+ PropVariant_SetFrom_DosTime(prop, item.ModifiedTime);
break;
}
// case kpidAttrib: prop = (UInt32)item.Attributes; break;
diff --git a/CPP/7zip/Archive/LzmaHandler.cpp b/CPP/7zip/Archive/LzmaHandler.cpp
index ba547c83..ba547c83 100644..100755
--- a/CPP/7zip/Archive/LzmaHandler.cpp
+++ b/CPP/7zip/Archive/LzmaHandler.cpp
diff --git a/CPP/7zip/Archive/MachoHandler.cpp b/CPP/7zip/Archive/MachoHandler.cpp
index bc8ba223..bc8ba223 100644..100755
--- a/CPP/7zip/Archive/MachoHandler.cpp
+++ b/CPP/7zip/Archive/MachoHandler.cpp
diff --git a/CPP/7zip/Archive/MbrHandler.cpp b/CPP/7zip/Archive/MbrHandler.cpp
index 026696f3..026696f3 100644..100755
--- a/CPP/7zip/Archive/MbrHandler.cpp
+++ b/CPP/7zip/Archive/MbrHandler.cpp
diff --git a/CPP/7zip/Archive/MslzHandler.cpp b/CPP/7zip/Archive/MslzHandler.cpp
index 6f9057a6..6f9057a6 100644..100755
--- a/CPP/7zip/Archive/MslzHandler.cpp
+++ b/CPP/7zip/Archive/MslzHandler.cpp
diff --git a/CPP/7zip/Archive/MubHandler.cpp b/CPP/7zip/Archive/MubHandler.cpp
index c790265d..c790265d 100644..100755
--- a/CPP/7zip/Archive/MubHandler.cpp
+++ b/CPP/7zip/Archive/MubHandler.cpp
diff --git a/CPP/7zip/Archive/Nsis/NsisDecode.cpp b/CPP/7zip/Archive/Nsis/NsisDecode.cpp
index e2822184..e2822184 100644..100755
--- a/CPP/7zip/Archive/Nsis/NsisDecode.cpp
+++ b/CPP/7zip/Archive/Nsis/NsisDecode.cpp
diff --git a/CPP/7zip/Archive/Nsis/NsisDecode.h b/CPP/7zip/Archive/Nsis/NsisDecode.h
index 2153d785..2153d785 100644..100755
--- a/CPP/7zip/Archive/Nsis/NsisDecode.h
+++ b/CPP/7zip/Archive/Nsis/NsisDecode.h
diff --git a/CPP/7zip/Archive/Nsis/NsisHandler.cpp b/CPP/7zip/Archive/Nsis/NsisHandler.cpp
index aa0a9175..aa0a9175 100644..100755
--- a/CPP/7zip/Archive/Nsis/NsisHandler.cpp
+++ b/CPP/7zip/Archive/Nsis/NsisHandler.cpp
diff --git a/CPP/7zip/Archive/Nsis/NsisHandler.h b/CPP/7zip/Archive/Nsis/NsisHandler.h
index 1eb8b731..1eb8b731 100644..100755
--- a/CPP/7zip/Archive/Nsis/NsisHandler.h
+++ b/CPP/7zip/Archive/Nsis/NsisHandler.h
diff --git a/CPP/7zip/Archive/Nsis/NsisIn.cpp b/CPP/7zip/Archive/Nsis/NsisIn.cpp
index 4e2d7a9d..4e2d7a9d 100644..100755
--- a/CPP/7zip/Archive/Nsis/NsisIn.cpp
+++ b/CPP/7zip/Archive/Nsis/NsisIn.cpp
diff --git a/CPP/7zip/Archive/Nsis/NsisIn.h b/CPP/7zip/Archive/Nsis/NsisIn.h
index 1d92e12f..1d92e12f 100644..100755
--- a/CPP/7zip/Archive/Nsis/NsisIn.h
+++ b/CPP/7zip/Archive/Nsis/NsisIn.h
diff --git a/CPP/7zip/Archive/Nsis/NsisRegister.cpp b/CPP/7zip/Archive/Nsis/NsisRegister.cpp
index 7230c3c2..7230c3c2 100644..100755
--- a/CPP/7zip/Archive/Nsis/NsisRegister.cpp
+++ b/CPP/7zip/Archive/Nsis/NsisRegister.cpp
diff --git a/CPP/7zip/Archive/Nsis/StdAfx.h b/CPP/7zip/Archive/Nsis/StdAfx.h
index 2854ff3e..2854ff3e 100644..100755
--- a/CPP/7zip/Archive/Nsis/StdAfx.h
+++ b/CPP/7zip/Archive/Nsis/StdAfx.h
diff --git a/CPP/7zip/Archive/NtfsHandler.cpp b/CPP/7zip/Archive/NtfsHandler.cpp
index daa01fef..7d0c6f78 100644..100755
--- a/CPP/7zip/Archive/NtfsHandler.cpp
+++ b/CPP/7zip/Archive/NtfsHandler.cpp
@@ -278,7 +278,7 @@ struct CSiAttr
{
UInt64 CTime;
UInt64 MTime;
- // UInt64 ThisRecMTime;
+ UInt64 ThisRecMTime;
UInt64 ATime;
UInt32 Attrib;
@@ -300,7 +300,7 @@ bool CSiAttr::Parse(const Byte *p, unsigned size)
return false;
G64(p + 0x00, CTime);
G64(p + 0x08, MTime);
- // G64(p + 0x10, ThisRecMTime);
+ G64(p + 0x10, ThisRecMTime);
G64(p + 0x18, ATime);
G32(p + 0x20, Attrib);
SecurityId = 0;
@@ -2301,6 +2301,7 @@ static const Byte kProps[] =
kpidMTime,
kpidCTime,
kpidATime,
+ kpidChangeTime,
kpidAttrib,
kpidLinks,
kpidINode,
@@ -2577,7 +2578,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidMTime: NtfsTimeToProp(rec.SiAttr.MTime, prop); break;
case kpidCTime: NtfsTimeToProp(rec.SiAttr.CTime, prop); break;
case kpidATime: NtfsTimeToProp(rec.SiAttr.ATime, prop); break;
- // case kpidRecMTime: if (fn) NtfsTimeToProp(rec.SiAttr.ThisRecMTime, prop); break;
+ case kpidChangeTime: NtfsTimeToProp(rec.SiAttr.ThisRecMTime, prop); break;
/*
case kpidMTime2: if (fn) NtfsTimeToProp(fn->MTime, prop); break;
diff --git a/CPP/7zip/Archive/PeHandler.cpp b/CPP/7zip/Archive/PeHandler.cpp
index ee265571..34a38acf 100644..100755
--- a/CPP/7zip/Archive/PeHandler.cpp
+++ b/CPP/7zip/Archive/PeHandler.cpp
@@ -885,11 +885,7 @@ IMP_IInArchive_ArcProps_WITH_NAME
static void TimeToProp(UInt32 unixTime, NCOM::CPropVariant &prop)
{
if (unixTime != 0)
- {
- FILETIME ft;
- NTime::UnixTimeToFileTime(unixTime, ft);
- prop = ft;
- }
+ PropVariant_SetFrom_UnixTime(prop, unixTime);
}
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
diff --git a/CPP/7zip/Archive/PpmdHandler.cpp b/CPP/7zip/Archive/PpmdHandler.cpp
index 05a07e53..101bfd98 100644..100755
--- a/CPP/7zip/Archive/PpmdHandler.cpp
+++ b/CPP/7zip/Archive/PpmdHandler.cpp
@@ -174,7 +174,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIAN
{
// time can be in Unix format ???
FILETIME utc;
- if (NTime::DosTimeToFileTime(_item.Time, utc))
+ if (NTime::DosTime_To_FileTime(_item.Time, utc))
prop = utc;
break;
}
diff --git a/CPP/7zip/Archive/QcowHandler.cpp b/CPP/7zip/Archive/QcowHandler.cpp
index 4a795eca..4a795eca 100644..100755
--- a/CPP/7zip/Archive/QcowHandler.cpp
+++ b/CPP/7zip/Archive/QcowHandler.cpp
diff --git a/CPP/7zip/Archive/Rar/Rar5Handler.cpp b/CPP/7zip/Archive/Rar/Rar5Handler.cpp
index bb8a2edb..563695f8 100644..100755
--- a/CPP/7zip/Archive/Rar/Rar5Handler.cpp
+++ b/CPP/7zip/Archive/Rar/Rar5Handler.cpp
@@ -1591,14 +1591,14 @@ STDMETHODIMP CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data
static void TimeRecordToProp(const CItem &item, unsigned stampIndex, NCOM::CPropVariant &prop)
{
unsigned size;
- int offset = item.FindExtra(NExtraID::kTime, size);
+ const int offset = item.FindExtra(NExtraID::kTime, size);
if (offset < 0)
return;
const Byte *p = item.Extra + (unsigned)offset;
UInt64 flags;
{
- unsigned num = ReadVarInt(p, size, &flags);
+ const unsigned num = ReadVarInt(p, size, &flags);
if (num == 0)
return;
p += num;
@@ -1610,8 +1610,8 @@ static void TimeRecordToProp(const CItem &item, unsigned stampIndex, NCOM::CProp
unsigned numStamps = 0;
unsigned curStamp = 0;
- unsigned i;
- for (i = 0; i < 3; i++)
+
+ for (unsigned i = 0; i < 3; i++)
if ((flags & (NTimeRecord::NFlags::kMTime << i)) != 0)
{
if (i == stampIndex)
@@ -1620,20 +1620,28 @@ static void TimeRecordToProp(const CItem &item, unsigned stampIndex, NCOM::CProp
}
FILETIME ft;
-
+
+ unsigned timePrec = 0;
+ unsigned ns100 = 0;
+
if ((flags & NTimeRecord::NFlags::kUnixTime) != 0)
{
curStamp *= 4;
if (curStamp + 4 > size)
return;
- const Byte *p2 = p + curStamp;
- UInt64 val = NTime::UnixTimeToFileTime64(Get32(p2));
+ p += curStamp;
+ UInt64 val = NTime::UnixTime_To_FileTime64(Get32(p));
numStamps *= 4;
+ timePrec = k_PropVar_TimePrec_Unix;
if ((flags & NTimeRecord::NFlags::kUnixNs) != 0 && numStamps * 2 <= size)
{
- const UInt32 ns = Get32(p2 + numStamps) & 0x3FFFFFFF;
+ const UInt32 ns = Get32(p + numStamps) & 0x3FFFFFFF;
if (ns < 1000000000)
+ {
val += ns / 100;
+ ns100 = (unsigned)(ns % 100);
+ timePrec = k_PropVar_TimePrec_1ns;
+ }
}
ft.dwLowDateTime = (DWORD)val;
ft.dwHighDateTime = (DWORD)(val >> 32);
@@ -1643,12 +1651,12 @@ static void TimeRecordToProp(const CItem &item, unsigned stampIndex, NCOM::CProp
curStamp *= 8;
if (curStamp + 8 > size)
return;
- const Byte *p2 = p + curStamp;
- ft.dwLowDateTime = Get32(p2);
- ft.dwHighDateTime = Get32(p2 + 4);
+ p += curStamp;
+ ft.dwLowDateTime = Get32(p);
+ ft.dwHighDateTime = Get32(p + 4);
}
- prop = ft;
+ prop.SetAsTimeFrom_FT_Prec_Ns100(ft, timePrec, ns100);
}
@@ -1715,21 +1723,13 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{
TimeRecordToProp(item, NTimeRecord::k_Index_MTime, prop);
if (prop.vt == VT_EMPTY && item.Has_UnixMTime())
- {
- FILETIME ft;
- NWindows::NTime::UnixTimeToFileTime(item.UnixMTime, ft);
- prop = ft;
- }
+ PropVariant_SetFrom_UnixTime(prop, item.UnixMTime);
if (prop.vt == VT_EMPTY && ref.Parent >= 0)
{
const CItem &baseItem = _items[_refs[ref.Parent].Item];
TimeRecordToProp(baseItem, NTimeRecord::k_Index_MTime, prop);
if (prop.vt == VT_EMPTY && baseItem.Has_UnixMTime())
- {
- FILETIME ft;
- NWindows::NTime::UnixTimeToFileTime(baseItem.UnixMTime, ft);
- prop = ft;
- }
+ PropVariant_SetFrom_UnixTime(prop, baseItem.UnixMTime);
}
break;
}
diff --git a/CPP/7zip/Archive/Rar/Rar5Handler.h b/CPP/7zip/Archive/Rar/Rar5Handler.h
index 3b3b940a..3b3b940a 100644..100755
--- a/CPP/7zip/Archive/Rar/Rar5Handler.h
+++ b/CPP/7zip/Archive/Rar/Rar5Handler.h
diff --git a/CPP/7zip/Archive/Rar/RarHandler.cpp b/CPP/7zip/Archive/Rar/RarHandler.cpp
index 7491c50b..ecadf853 100644..100755
--- a/CPP/7zip/Archive/Rar/RarHandler.cpp
+++ b/CPP/7zip/Archive/Rar/RarHandler.cpp
@@ -360,7 +360,7 @@ void CInArchive::ReadName(const Byte *p, unsigned nameSize, CItem &item)
static int ReadTime(const Byte *p, unsigned size, Byte mask, CRarTime &rarTime)
{
rarTime.LowSecond = (Byte)(((mask & 4) != 0) ? 1 : 0);
- unsigned numDigits = (mask & 3);
+ const unsigned numDigits = (mask & 3);
rarTime.SubTime[0] =
rarTime.SubTime[1] =
rarTime.SubTime[2] = 0;
@@ -405,8 +405,8 @@ bool CInArchive::ReadHeaderReal(const Byte *p, unsigned size, CItem &item)
item.MTime.LowSecond = 0;
item.MTime.SubTime[0] =
- item.MTime.SubTime[1] =
- item.MTime.SubTime[2] = 0;
+ item.MTime.SubTime[1] =
+ item.MTime.SubTime[2] = 0;
p += kFileHeaderSize;
size -= kFileHeaderSize;
@@ -941,31 +941,32 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
return S_OK;
}
-static bool RarTimeToFileTime(const CRarTime &rarTime, FILETIME &result)
+static bool RarTimeToFileTime(const CRarTime &rarTime, FILETIME &ft)
{
- if (!NTime::DosTimeToFileTime(rarTime.DosTime, result))
+ if (!NTime::DosTime_To_FileTime(rarTime.DosTime, ft))
return false;
- UInt64 value = (((UInt64)result.dwHighDateTime) << 32) + result.dwLowDateTime;
- value += (UInt64)rarTime.LowSecond * 10000000;
- value += ((UInt64)rarTime.SubTime[2] << 16) +
- ((UInt64)rarTime.SubTime[1] << 8) +
- ((UInt64)rarTime.SubTime[0]);
- result.dwLowDateTime = (DWORD)value;
- result.dwHighDateTime = DWORD(value >> 32);
+ UInt64 v = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
+ v += (UInt32)rarTime.LowSecond * 10000000;
+ v +=
+ ((UInt32)rarTime.SubTime[2] << 16) +
+ ((UInt32)rarTime.SubTime[1] << 8) +
+ ((UInt32)rarTime.SubTime[0]);
+ ft.dwLowDateTime = (DWORD)v;
+ ft.dwHighDateTime = (DWORD)(v >> 32);
return true;
}
static void RarTimeToProp(const CRarTime &rarTime, NCOM::CPropVariant &prop)
{
- FILETIME localFileTime, utcFileTime;
- if (RarTimeToFileTime(rarTime, localFileTime))
- {
- if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime))
- utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
- }
+ FILETIME localFileTime, utc;
+ if (RarTimeToFileTime(rarTime, localFileTime)
+ && LocalFileTimeToFileTime(&localFileTime, &utc))
+ prop.SetAsTimeFrom_FT_Prec(utc, k_PropVar_TimePrec_100ns);
+ /*
else
- utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
- prop = utcFileTime;
+ utc.dwHighDateTime = utc.dwLowDateTime = 0;
+ // prop.SetAsTimeFrom_FT_Prec(utc, k_PropVar_TimePrec_100ns);
+ */
}
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
diff --git a/CPP/7zip/Archive/Rar/RarHandler.h b/CPP/7zip/Archive/Rar/RarHandler.h
index a62b60cd..a62b60cd 100644..100755
--- a/CPP/7zip/Archive/Rar/RarHandler.h
+++ b/CPP/7zip/Archive/Rar/RarHandler.h
diff --git a/CPP/7zip/Archive/Rar/RarHeader.h b/CPP/7zip/Archive/Rar/RarHeader.h
index 30c53ec9..30c53ec9 100644..100755
--- a/CPP/7zip/Archive/Rar/RarHeader.h
+++ b/CPP/7zip/Archive/Rar/RarHeader.h
diff --git a/CPP/7zip/Archive/Rar/RarItem.h b/CPP/7zip/Archive/Rar/RarItem.h
index 10e21c57..10e21c57 100644..100755
--- a/CPP/7zip/Archive/Rar/RarItem.h
+++ b/CPP/7zip/Archive/Rar/RarItem.h
diff --git a/CPP/7zip/Archive/Rar/RarVol.h b/CPP/7zip/Archive/Rar/RarVol.h
index 96264330..2f5bbd37 100644..100755
--- a/CPP/7zip/Archive/Rar/RarVol.h
+++ b/CPP/7zip/Archive/Rar/RarVol.h
@@ -52,7 +52,7 @@ public:
ext.IsEqualTo_Ascii_NoCase("r01"))
{
_changed = ext;
- _before = name.Left(dotPos + 1);
+ _before.SetFrom(name.Ptr(), dotPos + 1);
return true;
}
}
@@ -60,16 +60,23 @@ public:
if (newStyle)
{
- unsigned i = base.Len();
+ unsigned k = base.Len();
+
+ for (; k != 0; k--)
+ if (IsDigit(base[k - 1]))
+ break;
+
+ unsigned i = k;
for (; i != 0; i--)
if (!IsDigit(base[i - 1]))
break;
- if (i != base.Len())
+ if (i != k)
{
- _before = base.Left(i);
- _changed = base.Ptr(i);
+ _before.SetFrom(base.Ptr(), i);
+ _changed.SetFrom(base.Ptr(i), k - i);
+ _after.Insert(0, base.Ptr(k));
return true;
}
}
diff --git a/CPP/7zip/Archive/Rar/StdAfx.cpp b/CPP/7zip/Archive/Rar/StdAfx.cpp
index d0feea85..d0feea85 100644..100755
--- a/CPP/7zip/Archive/Rar/StdAfx.cpp
+++ b/CPP/7zip/Archive/Rar/StdAfx.cpp
diff --git a/CPP/7zip/Archive/Rar/StdAfx.h b/CPP/7zip/Archive/Rar/StdAfx.h
index 2854ff3e..2854ff3e 100644..100755
--- a/CPP/7zip/Archive/Rar/StdAfx.h
+++ b/CPP/7zip/Archive/Rar/StdAfx.h
diff --git a/CPP/7zip/Archive/RpmHandler.cpp b/CPP/7zip/Archive/RpmHandler.cpp
index e0ec28ce..366f8efb 100644..100755
--- a/CPP/7zip/Archive/RpmHandler.cpp
+++ b/CPP/7zip/Archive/RpmHandler.cpp
@@ -215,11 +215,7 @@ class CHandler: public CHandlerCont
void SetTime(NCOM::CPropVariant &prop) const
{
if (_time_Defined && _buildTime != 0)
- {
- FILETIME ft;
- NTime::UnixTimeToFileTime(_buildTime, ft);
- prop = ft;
- }
+ PropVariant_SetFrom_UnixTime(prop, _buildTime);
}
void SetStringProp(const AString &s, NCOM::CPropVariant &prop) const
diff --git a/CPP/7zip/Archive/SparseHandler.cpp b/CPP/7zip/Archive/SparseHandler.cpp
new file mode 100755
index 00000000..47e3ed8d
--- /dev/null
+++ b/CPP/7zip/Archive/SparseHandler.cpp
@@ -0,0 +1,548 @@
+// SparseHandler.cpp
+
+#include "StdAfx.h"
+
+#include "../../../C/CpuArch.h"
+
+#include "../../Common/ComTry.h"
+
+#include "../../Windows/PropVariantUtils.h"
+
+#include "../Common/RegisterArc.h"
+#include "../Common/StreamUtils.h"
+
+#include "HandlerCont.h"
+
+#define Get16(p) GetUi16(p)
+#define Get32(p) GetUi32(p)
+
+#define G16(_offs_, dest) dest = Get16(p + (_offs_));
+#define G32(_offs_, dest) dest = Get32(p + (_offs_));
+
+using namespace NWindows;
+
+namespace NArchive {
+namespace NSparse {
+
+// libsparse and simg2img
+
+struct CHeader
+{
+ // UInt32 magic; /* 0xed26ff3a */
+ // UInt16 major_version; /* (0x1) - reject images with higher major versions */
+ // UInt16 minor_version; /* (0x0) - allow images with higer minor versions */
+ UInt16 file_hdr_sz; /* 28 bytes for first revision of the file format */
+ UInt16 chunk_hdr_sz; /* 12 bytes for first revision of the file format */
+ UInt32 BlockSize; /* block size in bytes, must be a multiple of 4 (4096) */
+ UInt32 NumBlocks; /* total blocks in the non-sparse output image */
+ UInt32 NumChunks; /* total chunks in the sparse input image */
+ // UInt32 image_checksum; /* CRC32 checksum of the original data, counting "don't care" as 0. */
+
+ void Parse(const Byte *p)
+ {
+ // G16 (4, major_version);
+ // G16 (6, minor_version);
+ G16 (8, file_hdr_sz);
+ G16 (10, chunk_hdr_sz);
+ G32 (12, BlockSize);
+ G32 (16, NumBlocks);
+ G32 (20, NumChunks);
+ // G32 (24, image_checksum);
+ }
+};
+
+// #define SPARSE_HEADER_MAGIC 0xed26ff3a
+
+#define CHUNK_TYPE_RAW 0xCAC1
+#define CHUNK_TYPE_FILL 0xCAC2
+#define CHUNK_TYPE_DONT_CARE 0xCAC3
+#define CHUNK_TYPE_CRC32 0xCAC4
+
+#define MY__CHUNK_TYPE_FILL 0
+#define MY__CHUNK_TYPE_DONT_CARE 1
+#define MY__CHUNK_TYPE_RAW__START 2
+
+static const char * const g_Methods[] =
+{
+ "RAW"
+ , "FILL"
+ , "SPARSE" // "DONT_CARE"
+ , "CRC32"
+};
+
+static const unsigned kFillSize = 4;
+
+struct CChunk
+{
+ UInt32 VirtBlock;
+ Byte Fill [kFillSize];
+ UInt64 PhyOffset;
+};
+
+static const Byte k_Signature[] = { 0x3a, 0xff, 0x26, 0xed, 1, 0 };
+
+
+class CHandler: public CHandlerImg
+{
+ CRecordVector<CChunk> Chunks;
+ UInt64 _virtSize_fromChunks;
+ unsigned _blockSizeLog;
+ UInt32 _chunkIndexPrev;
+
+ UInt64 _packSizeProcessed;
+ UInt64 _phySize;
+ UInt32 _methodFlags;
+ bool _isArc;
+ bool _headersError;
+ bool _unexpectedEnd;
+ // bool _unsupported;
+ UInt32 NumChunks; // from header
+
+ HRESULT Seek2(UInt64 offset)
+ {
+ _posInArc = offset;
+ return Stream->Seek(offset, STREAM_SEEK_SET, NULL);
+ }
+
+ void InitSeekPositions()
+ {
+ /* (_virtPos) and (_posInArc) is used only in Read() (that calls ReadPhy()).
+ So we must reset these variables before first call of Read() */
+ Reset_VirtPos();
+ Reset_PosInArc();
+ _chunkIndexPrev = 0;
+ _packSizeProcessed = 0;
+ }
+
+ // virtual functions
+ bool Init_PackSizeProcessed()
+ {
+ _packSizeProcessed = 0;
+ return true;
+ }
+ bool Get_PackSizeProcessed(UInt64 &size)
+ {
+ size = _packSizeProcessed;
+ return true;
+ }
+
+ HRESULT Open2(IInStream *stream, IArchiveOpenCallback *openCallback);
+ HRESULT ReadPhy(UInt64 offset, void *data, UInt32 size, UInt32 &processed);
+
+public:
+ INTERFACE_IInArchive_Img(;)
+
+ STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+};
+
+
+
+static const Byte kProps[] =
+{
+ kpidSize,
+ kpidPackSize
+};
+
+static const Byte kArcProps[] =
+{
+ kpidClusterSize,
+ kpidNumBlocks,
+ kpidMethod
+};
+
+IMP_IInArchive_Props
+IMP_IInArchive_ArcProps
+
+STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NCOM::CPropVariant prop;
+
+ switch (propID)
+ {
+ case kpidMainSubfile: prop = (UInt32)0; break;
+ case kpidClusterSize: prop = (UInt32)((UInt32)1 << _blockSizeLog); break;
+ case kpidNumBlocks: prop = (UInt32)NumChunks; break;
+ case kpidPhySize: if (_phySize != 0) prop = _phySize; break;
+
+ case kpidMethod:
+ {
+ FLAGS_TO_PROP(g_Methods, _methodFlags, prop);
+ break;
+ }
+
+ case kpidErrorFlags:
+ {
+ UInt32 v = 0;
+ if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;
+ if (_headersError) v |= kpv_ErrorFlags_HeadersError;
+ if (_unexpectedEnd) v |= kpv_ErrorFlags_UnexpectedEnd;
+ // if (_unsupported) v |= kpv_ErrorFlags_UnsupportedMethod;
+ if (!Stream && v == 0 && _isArc)
+ v = kpv_ErrorFlags_HeadersError;
+ if (v != 0)
+ prop = v;
+ break;
+ }
+ }
+
+ prop.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+
+STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NCOM::CPropVariant prop;
+
+ switch (propID)
+ {
+ case kpidSize: prop = _size; break;
+ case kpidPackSize: prop = _phySize; break;
+ case kpidExtension: prop = (_imgExt ? _imgExt : "img"); break;
+ }
+
+ prop.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+
+static unsigned GetLogSize(UInt32 size)
+{
+ unsigned k;
+ for (k = 0; k < 32; k++)
+ if (((UInt32)1 << k) == size)
+ return k;
+ return k;
+}
+
+
+HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *openCallback)
+{
+ const unsigned kHeaderSize = 28;
+ const unsigned kChunkHeaderSize = 12;
+ CHeader h;
+ {
+ Byte buf[kHeaderSize];
+ RINOK(ReadStream_FALSE(stream, buf, kHeaderSize));
+ if (memcmp(buf, k_Signature, 6) != 0)
+ return S_FALSE;
+ h.Parse(buf);
+ }
+
+ if (h.file_hdr_sz != kHeaderSize ||
+ h.chunk_hdr_sz != kChunkHeaderSize)
+ return S_FALSE;
+
+ NumChunks = h.NumChunks;
+
+ const unsigned logSize = GetLogSize(h.BlockSize);
+ if (logSize < 2 || logSize >= 32)
+ return S_FALSE;
+ _blockSizeLog = logSize;
+
+ _size = (UInt64)h.NumBlocks << logSize;
+
+ if (h.NumChunks >= (UInt32)(Int32)-2) // it's our limit
+ return S_FALSE;
+
+ _isArc = true;
+ Chunks.Reserve(h.NumChunks + 1);
+ UInt64 offset = kHeaderSize;
+ UInt32 virtBlock = 0;
+ UInt32 i;
+
+ for (i = 0; i < h.NumChunks; i++)
+ {
+ {
+ const UInt32 mask = ((UInt32)1 << 16) - 1;
+ if ((i & mask) == mask && openCallback)
+ {
+ RINOK(openCallback->SetCompleted(NULL, &offset));
+ }
+ }
+ Byte buf[kChunkHeaderSize];
+ {
+ size_t processed = kChunkHeaderSize;
+ RINOK(ReadStream(stream, buf, &processed));
+ if (kChunkHeaderSize != processed)
+ {
+ offset += kChunkHeaderSize;
+ break;
+ }
+ }
+ const UInt32 type = Get32(&buf[0]);
+ const UInt32 numBlocks = Get32(&buf[4]);
+ UInt32 size = Get32(&buf[8]);
+
+ if (type < CHUNK_TYPE_RAW ||
+ type > CHUNK_TYPE_CRC32)
+ return S_FALSE;
+ if (size < kChunkHeaderSize)
+ return S_FALSE;
+ CChunk c;
+ c.PhyOffset = offset + kChunkHeaderSize;
+ c.VirtBlock = virtBlock;
+ offset += size;
+ size -= kChunkHeaderSize;
+ _methodFlags |= ((UInt32)1 << (type - CHUNK_TYPE_RAW));
+
+ if (numBlocks > h.NumBlocks - virtBlock)
+ return S_FALSE;
+
+ if (type == CHUNK_TYPE_CRC32)
+ {
+ // crc chunk must be last chunk (i == h.NumChunks -1);
+ if (size != kFillSize || numBlocks != 0)
+ return S_FALSE;
+ {
+ size_t processed = kFillSize;
+ RINOK(ReadStream(stream, c.Fill, &processed));
+ if (kFillSize != processed)
+ break;
+ }
+ continue;
+ }
+ // else
+ {
+ if (numBlocks == 0)
+ return S_FALSE;
+
+ if (type == CHUNK_TYPE_DONT_CARE)
+ {
+ if (size != 0)
+ return S_FALSE;
+ c.PhyOffset = MY__CHUNK_TYPE_DONT_CARE;
+ }
+ else if (type == CHUNK_TYPE_FILL)
+ {
+ if (size != kFillSize)
+ return S_FALSE;
+ c.PhyOffset = MY__CHUNK_TYPE_FILL;
+ size_t processed = kFillSize;
+ RINOK(ReadStream(stream, c.Fill, &processed));
+ if (kFillSize != processed)
+ break;
+ }
+ else if (type == CHUNK_TYPE_RAW)
+ {
+ /* Here we require (size == virtSize).
+ Probably original decoder also requires it.
+ But maybe size of last chunk can be non-aligned with blockSize ? */
+ const UInt32 virtSize = (numBlocks << _blockSizeLog);
+ if (size != virtSize || numBlocks != (virtSize >> _blockSizeLog))
+ return S_FALSE;
+ }
+ else
+ return S_FALSE;
+
+ virtBlock += numBlocks;
+ Chunks.AddInReserved(c);
+ if (type == CHUNK_TYPE_RAW)
+ RINOK(stream->Seek(offset, STREAM_SEEK_SET, NULL));
+ }
+ }
+
+ if (i != h.NumChunks)
+ _unexpectedEnd = true;
+ else if (virtBlock != h.NumBlocks)
+ _headersError = true;
+
+ _phySize = offset;
+
+ {
+ CChunk c;
+ c.VirtBlock = virtBlock;
+ c.PhyOffset = offset;
+ Chunks.AddInReserved(c);
+ }
+ _virtSize_fromChunks = (UInt64)virtBlock << _blockSizeLog;
+
+ Stream = stream;
+ return S_OK;
+}
+
+
+STDMETHODIMP CHandler::Close()
+{
+ Chunks.Clear();
+ _isArc = false;
+ _virtSize_fromChunks = 0;
+ // _unsupported = false;
+ _headersError = false;
+ _unexpectedEnd = false;
+ _phySize = 0;
+ _methodFlags = 0;
+
+ _chunkIndexPrev = 0;
+ _packSizeProcessed = 0;
+
+ // CHandlerImg:
+ Clear_HandlerImg_Vars();
+ Stream.Release();
+ return S_OK;
+}
+
+
+STDMETHODIMP CHandler::GetStream(UInt32 /* index */, ISequentialInStream **stream)
+{
+ COM_TRY_BEGIN
+ *stream = NULL;
+ if (Chunks.Size() < 1)
+ return S_FALSE;
+ if (Chunks.Size() < 2 && _virtSize_fromChunks != 0)
+ return S_FALSE;
+ // if (_unsupported) return S_FALSE;
+ InitSeekPositions();
+ CMyComPtr<ISequentialInStream> streamTemp = this;
+ *stream = streamTemp.Detach();
+ return S_OK;
+ COM_TRY_END
+}
+
+
+
+HRESULT CHandler::ReadPhy(UInt64 offset, void *data, UInt32 size, UInt32 &processed)
+{
+ processed = 0;
+ if (offset > _phySize || offset + size > _phySize)
+ {
+ // we don't expect these cases, if (_phySize) was set correctly.
+ return S_FALSE;
+ }
+ if (offset != _posInArc)
+ {
+ const HRESULT res = Seek2(offset);
+ if (res != S_OK)
+ {
+ Reset_PosInArc(); // we don't trust seek_pos in case of error
+ return res;
+ }
+ }
+ {
+ size_t size2 = size;
+ const HRESULT res = ReadStream(Stream, data, &size2);
+ processed = (UInt32)size2;
+ _packSizeProcessed += size2;
+ _posInArc += size2;
+ if (res != S_OK)
+ Reset_PosInArc(); // we don't trust seek_pos in case of reading error
+ return res;
+ }
+}
+
+
+STDMETHODIMP CHandler::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ if (processedSize)
+ *processedSize = 0;
+ // const unsigned kLimit = (1 << 16) + 1; if (size > kLimit) size = kLimit; // for debug
+ if (_virtPos >= _virtSize_fromChunks)
+ return S_OK;
+ {
+ const UInt64 rem = _virtSize_fromChunks - _virtPos;
+ if (size > rem)
+ size = (UInt32)rem;
+ if (size == 0)
+ return S_OK;
+ }
+
+ UInt32 chunkIndex = _chunkIndexPrev;
+ if (chunkIndex + 1 >= Chunks.Size())
+ return S_FALSE;
+ {
+ const UInt32 blockIndex = (UInt32)(_virtPos >> _blockSizeLog);
+ if (blockIndex < Chunks[chunkIndex ].VirtBlock ||
+ blockIndex >= Chunks[chunkIndex + 1].VirtBlock)
+ {
+ unsigned left = 0, right = Chunks.Size() - 1;
+ for (;;)
+ {
+ const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2);
+ if (mid == left)
+ break;
+ if (blockIndex < Chunks[mid].VirtBlock)
+ right = mid;
+ else
+ left = mid;
+ }
+ chunkIndex = left;
+ _chunkIndexPrev = chunkIndex;
+ }
+ }
+
+ const CChunk &c = Chunks[chunkIndex];
+ const UInt64 offset = _virtPos - ((UInt64)c.VirtBlock << _blockSizeLog);
+ {
+ const UInt32 numBlocks = Chunks[chunkIndex + 1].VirtBlock - c.VirtBlock;
+ const UInt64 rem = ((UInt64)numBlocks << _blockSizeLog) - offset;
+ if (size > rem)
+ size = (UInt32)rem;
+ }
+
+ const UInt64 phyOffset = c.PhyOffset;
+
+ if (phyOffset >= MY__CHUNK_TYPE_RAW__START)
+ {
+ UInt32 processed = 0;
+ const HRESULT res = ReadPhy(phyOffset + offset, data, size, processed);
+ if (processedSize)
+ *processedSize = processed;
+ _virtPos += processed;
+ return res;
+ }
+
+ unsigned b = 0;
+
+ if (phyOffset == MY__CHUNK_TYPE_FILL)
+ {
+ const Byte b0 = c.Fill [0];
+ const Byte b1 = c.Fill [1];
+ const Byte b2 = c.Fill [2];
+ const Byte b3 = c.Fill [3];
+ if (b0 != b1 ||
+ b0 != b2 ||
+ b0 != b3)
+ {
+ if (processedSize)
+ *processedSize = size;
+ _virtPos += size;
+ Byte *dest = (Byte *)data;
+ while (size >= 4)
+ {
+ dest[0] = b0;
+ dest[1] = b1;
+ dest[2] = b2;
+ dest[3] = b3;
+ dest += 4;
+ size -= 4;
+ }
+ if (size > 0) dest[0] = b0;
+ if (size > 1) dest[1] = b1;
+ if (size > 2) dest[2] = b2;
+ return S_OK;
+ }
+ b = b0;
+ }
+ else if (phyOffset != MY__CHUNK_TYPE_DONT_CARE)
+ return S_FALSE;
+
+ memset(data, b, size);
+ _virtPos += size;
+ if (processedSize)
+ *processedSize = size;
+ return S_OK;
+}
+
+REGISTER_ARC_I(
+ "Sparse", "simg img", NULL, 0xc2,
+ k_Signature,
+ 0,
+ 0,
+ NULL)
+
+}}
diff --git a/CPP/7zip/Archive/SplitHandler.cpp b/CPP/7zip/Archive/SplitHandler.cpp
index 6705aee0..6bddfb83 100644..100755
--- a/CPP/7zip/Archive/SplitHandler.cpp
+++ b/CPP/7zip/Archive/SplitHandler.cpp
@@ -162,7 +162,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 +173,7 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
break;
numLetters++;
}
- if (numLetters != ext.Len())
+ if (numLetters != ext2.Len())
return S_FALSE;
}
else
diff --git a/CPP/7zip/Archive/SquashfsHandler.cpp b/CPP/7zip/Archive/SquashfsHandler.cpp
index 74bc8fb8..fe271bc3 100644..100755
--- a/CPP/7zip/Archive/SquashfsHandler.cpp
+++ b/CPP/7zip/Archive/SquashfsHandler.cpp
@@ -76,7 +76,7 @@ static const char * const k_Methods[] =
, "XZ"
};
-static const UInt32 kMetadataBlockSizeLog = 13;
+static const unsigned kMetadataBlockSizeLog = 13;
static const UInt32 kMetadataBlockSize = (1 << kMetadataBlockSizeLog);
enum
@@ -408,7 +408,7 @@ UInt32 CNode::Parse1(const Byte *p, UInt32 size, const CHeader &_h)
UInt32 CNode::Parse2(const Byte *p, UInt32 size, const CHeader &_h)
{
- bool be = _h.be;
+ const bool be = _h.be;
if (size < 4)
return 0;
{
@@ -541,7 +541,7 @@ UInt32 CNode::Parse2(const Byte *p, UInt32 size, const CHeader &_h)
UInt32 CNode::Parse3(const Byte *p, UInt32 size, const CHeader &_h)
{
- bool be = _h.be;
+ const bool be = _h.be;
if (size < 12)
return 0;
@@ -843,8 +843,8 @@ class CHandler:
CData _inodesData;
CData _dirs;
CRecordVector<CFrag> _frags;
- // CByteBuffer _uids;
- // CByteBuffer _gids;
+ CByteBuffer _uids;
+ CByteBuffer _gids;
CHeader _h;
bool _noPropsLZMA;
bool _needCheckLzma;
@@ -891,14 +891,20 @@ class CHandler:
_cachedUnpackBlockSize = 0;
}
+ HRESULT Seek2(UInt64 offset)
+ {
+ return _stream->Seek(offset, STREAM_SEEK_SET, NULL);
+ }
+
HRESULT Decompress(ISequentialOutStream *outStream, Byte *outBuf, bool *outBufWasWritten, UInt32 *outBufWasWrittenSize,
UInt32 inSize, UInt32 outSizeMax);
HRESULT ReadMetadataBlock(UInt32 &packSize);
+ HRESULT ReadMetadataBlock2();
HRESULT ReadData(CData &data, UInt64 start, UInt64 end);
HRESULT OpenDir(int parent, UInt32 startBlock, UInt32 offset, unsigned level, int &nodeIndex);
HRESULT ScanInodes(UInt64 ptr);
- // HRESULT ReadUids(UInt64 start, UInt32 num, CByteBuffer &ids);
+ HRESULT ReadUids(UInt64 start, UInt32 num, CByteBuffer &ids);
HRESULT Open2(IInStream *inStream);
AString GetPath(int index) const;
bool GetPackSize(int index, UInt64 &res, bool fillOffsets);
@@ -938,9 +944,9 @@ static const Byte kProps[] =
kpidSize,
kpidPackSize,
kpidMTime,
- kpidPosixAttrib
- // kpidUser,
- // kpidGroup,
+ kpidPosixAttrib,
+ kpidUserId,
+ kpidGroupId
// kpidLinks,
// kpidOffset
};
@@ -1280,14 +1286,14 @@ HRESULT CHandler::Decompress(ISequentialOutStream *outStream, Byte *outBuf, bool
HRESULT CHandler::ReadMetadataBlock(UInt32 &packSize)
{
Byte temp[3];
- unsigned offset = _h.NeedCheckData() ? 3 : 2;
+ const unsigned offset = _h.NeedCheckData() ? 3 : 2;
if (offset > packSize)
return S_FALSE;
RINOK(ReadStream_FALSE(_stream, temp, offset));
// if (NeedCheckData && Major < 4) checkByte must be = 0xFF
- bool be = _h.be;
+ const bool be = _h.be;
UInt32 size = Get16(temp);
- bool isCompressed = ((size & kNotCompressedBit16) == 0);
+ const bool isCompressed = ((size & kNotCompressedBit16) == 0);
if (size != kNotCompressedBit16)
size &= ~kNotCompressedBit16;
@@ -1311,12 +1317,20 @@ HRESULT CHandler::ReadMetadataBlock(UInt32 &packSize)
return S_OK;
}
+
+HRESULT CHandler::ReadMetadataBlock2()
+{
+ _dynOutStreamSpec->Init();
+ UInt32 packSize = kMetadataBlockSize + 3; // check it
+ return ReadMetadataBlock(packSize);
+}
+
HRESULT CHandler::ReadData(CData &data, UInt64 start, UInt64 end)
{
if (end < start || end - start >= ((UInt64)1 << 32))
return S_FALSE;
const UInt32 size = (UInt32)(end - start);
- RINOK(_stream->Seek(start, STREAM_SEEK_SET, NULL));
+ RINOK(Seek2(start));
_dynOutStreamSpec->Init();
UInt32 packPos = 0;
while (packPos != size)
@@ -1395,7 +1409,7 @@ HRESULT CHandler::OpenDir(int parent, UInt32 startBlock, UInt32 offset, unsigned
CRecordVector<CTempItem> tempItems;
while (rem != 0)
{
- bool be = _h.be;
+ const bool be = _h.be;
UInt32 count;
CTempItem tempItem;
if (_h.Major <= 2)
@@ -1519,15 +1533,15 @@ HRESULT CHandler::OpenDir(int parent, UInt32 startBlock, UInt32 offset, unsigned
return S_OK;
}
-/*
HRESULT CHandler::ReadUids(UInt64 start, UInt32 num, CByteBuffer &ids)
{
- size_t size = num * 4;
- ids.SetCapacity(size);
- RINOK(_stream->Seek(start, STREAM_SEEK_SET, NULL));
+ const size_t size = (size_t)num * 4;
+ ids.Alloc(size);
+ if (num == 0)
+ return S_OK;
+ RINOK(Seek2(start));
return ReadStream_FALSE(_stream, ids, size);
}
-*/
HRESULT CHandler::Open2(IInStream *inStream)
{
@@ -1560,24 +1574,22 @@ HRESULT CHandler::Open2(IInStream *inStream)
if (_h.NumFrags > kNumFilesMax)
return S_FALSE;
_frags.ClearAndReserve(_h.NumFrags);
- unsigned bigFrag = (_h.Major > 2);
+ const unsigned bigFrag = (_h.Major > 2);
- unsigned fragPtrsInBlockLog = kMetadataBlockSizeLog - (3 + bigFrag);
- UInt32 numBlocks = (_h.NumFrags + (1 << fragPtrsInBlockLog) - 1) >> fragPtrsInBlockLog;
- size_t numBlocksBytes = (size_t)numBlocks << (2 + bigFrag);
+ const unsigned fragPtrsInBlockLog = kMetadataBlockSizeLog - (3 + bigFrag);
+ const UInt32 numBlocks = (_h.NumFrags + (1 << fragPtrsInBlockLog) - 1) >> fragPtrsInBlockLog;
+ const size_t numBlocksBytes = (size_t)numBlocks << (2 + bigFrag);
CByteBuffer data(numBlocksBytes);
- RINOK(inStream->Seek(_h.FragTable, STREAM_SEEK_SET, NULL));
+ RINOK(Seek2(_h.FragTable));
RINOK(ReadStream_FALSE(inStream, data, numBlocksBytes));
- bool be = _h.be;
+ const bool be = _h.be;
for (UInt32 i = 0; i < numBlocks; i++)
{
- UInt64 offset = bigFrag ? Get64(data + i * 8) : Get32(data + i * 4);
- RINOK(_stream->Seek(offset, STREAM_SEEK_SET, NULL));
- _dynOutStreamSpec->Init();
- UInt32 packSize = kMetadataBlockSize + 3;
- RINOK(ReadMetadataBlock(packSize));
- UInt32 unpackSize = (UInt32)_dynOutStreamSpec->GetSize();
+ const UInt64 offset = bigFrag ? Get64(data + i * 8) : Get32(data + i * 4);
+ RINOK(Seek2(offset));
+ RINOK(ReadMetadataBlock2());
+ const UInt32 unpackSize = (UInt32)_dynOutStreamSpec->GetSize();
if (unpackSize != kMetadataBlockSize)
if (i != numBlocks - 1 || unpackSize != ((_h.NumFrags << (3 + bigFrag)) & (kMetadataBlockSize - 1)))
return S_FALSE;
@@ -1605,8 +1617,6 @@ HRESULT CHandler::Open2(IInStream *inStream)
return S_FALSE;
}
- // RINOK(inStream->Seek(_h.InodeTable, STREAM_SEEK_SET, NULL));
-
RINOK(ReadData(_inodesData, _h.InodeTable, _h.DirTable));
RINOK(ReadData(_dirs, _h.DirTable, _h.FragTable));
@@ -1655,7 +1665,6 @@ HRESULT CHandler::Open2(IInStream *inStream)
int rootNodeIndex;
RINOK(OpenDir(-1, (UInt32)absOffset, (UInt32)_h.RootInode & 0xFFFF, 0, rootNodeIndex));
- /*
if (_h.Major < 4)
{
RINOK(ReadUids(_h.UidTable, _h.NumUids, _uids));
@@ -1663,33 +1672,34 @@ HRESULT CHandler::Open2(IInStream *inStream)
}
else
{
- UInt32 size = _h.NumIDs * 4;
- _uids.SetCapacity(size);
+ const UInt32 size = (UInt32)_h.NumIDs * 4;
+ _uids.Alloc(size);
- UInt32 numBlocks = (size + kMetadataBlockSize - 1) / kMetadataBlockSize;
- UInt32 numBlocksBytes = numBlocks << 3;
+ const UInt32 numBlocks = (size + kMetadataBlockSize - 1) / kMetadataBlockSize;
+ const UInt32 numBlocksBytes = numBlocks << 3;
CByteBuffer data;
- data.SetCapacity(numBlocksBytes);
- RINOK(inStream->Seek(_h.UidTable, STREAM_SEEK_SET, NULL));
+ data.Alloc(numBlocksBytes);
+ RINOK(Seek2(_h.UidTable));
RINOK(ReadStream_FALSE(inStream, data, numBlocksBytes));
for (UInt32 i = 0; i < numBlocks; i++)
{
- UInt64 offset = GetUi64(data + i * 8);
- UInt32 unpackSize, packSize;
- RINOK(_stream->Seek(offset, STREAM_SEEK_SET, NULL));
- RINOK(ReadMetadataBlock(NULL, _uids + kMetadataBlockSize * i, packSize, unpackSize));
+ const UInt64 offset = GetUi64(data + i * 8);
+ RINOK(Seek2(offset));
+ // RINOK(ReadMetadataBlock(NULL, _uids + kMetadataBlockSize * i, packSize, unpackSize));
+ RINOK(ReadMetadataBlock2());
+ const size_t unpackSize = _dynOutStreamSpec->GetSize();
if (unpackSize != kMetadataBlockSize)
if (i != numBlocks - 1 || unpackSize != (size & (kMetadataBlockSize - 1)))
return S_FALSE;
+ memcpy(_uids + kMetadataBlockSize * i, _dynOutStreamSpec->GetBuffer(), unpackSize);
}
}
- */
{
const UInt32 alignSize = 1 << 12;
Byte buf[alignSize];
- RINOK(inStream->Seek(_h.Size, STREAM_SEEK_SET, NULL));
+ RINOK(Seek2(_h.Size));
UInt32 rem = (UInt32)(0 - _h.Size) & (alignSize - 1);
_sizeCalculated = _h.Size;
if (rem != 0)
@@ -1710,7 +1720,7 @@ AString CHandler::GetPath(int index) const
{
unsigned len = 0;
int indexMem = index;
- bool be = _h.be;
+ const bool be = _h.be;
do
{
const CItem &item = _items[index];
@@ -1804,9 +1814,9 @@ bool CHandler::GetPackSize(int index, UInt64 &totalPack, bool fillOffsets)
totalPack = 0;
const CItem &item = _items[index];
const CNode &node = _nodes[item.Node];
- UInt32 ptr = _nodesPos[item.Node];
+ const UInt32 ptr = _nodesPos[item.Node];
const Byte *p = _inodesData.Data + ptr;
- bool be = _h.be;
+ const bool be = _h.be;
UInt32 type = node.Type;
UInt32 offset;
@@ -1936,11 +1946,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
case kpidBigEndian: prop = _h.be; break;
case kpidCTime:
if (_h.CTime != 0)
- {
- FILETIME ft;
- NWindows::NTime::UnixTimeToFileTime(_h.CTime, ft);
- prop = ft;
- }
+ PropVariant_SetFrom_UnixTime(prop, _h.CTime);
break;
case kpidCharacts: FLAGS_TO_PROP(k_Flags, _h.Flags, prop); break;
// case kpidNumBlocks: prop = _h.NumFrags; break;
@@ -1979,8 +1985,8 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
NWindows::NCOM::CPropVariant prop;
const CItem &item = _items[index];
const CNode &node = _nodes[item.Node];
- bool isDir = node.IsDir();
- bool be = _h.be;
+ const bool isDir = node.IsDir();
+ const bool be = _h.be;
switch (propID)
{
@@ -2031,9 +2037,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
if (offset != 0)
{
const Byte *p = _inodesData.Data + _nodesPos[item.Node] + offset;
- FILETIME ft;
- NWindows::NTime::UnixTimeToFileTime(Get32(p), ft);
- prop = ft;
+ PropVariant_SetFrom_UnixTime(prop, Get32(p));
}
break;
}
@@ -2043,31 +2047,38 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
prop = (UInt32)(node.Mode & 0xFFF) | k_TypeToMode[node.Type];
break;
}
- /*
- case kpidUser:
+ case kpidUserId:
{
- UInt32 offset = node.Uid * 4;
+ const UInt32 offset = (UInt32)node.Uid * 4;
if (offset < _uids.Size())
prop = (UInt32)Get32(_uids + offset);
break;
}
- case kpidGroup:
+ case kpidGroupId:
{
- if (_h.Major == 4 || node.Gid == _h.GetSpecGuidIndex())
+ if (_h.Major < 4)
{
- UInt32 offset = node.Uid * 4;
- if (offset < _uids.Size())
- prop = (UInt32)Get32(_uids + offset);
+ if (node.Gid == _h.GetSpecGuidIndex())
+ {
+ const UInt32 offset = (UInt32)node.Uid * 4;
+ if (offset < _uids.Size())
+ prop = (UInt32)Get32(_uids + offset);
+ }
+ else
+ {
+ const UInt32 offset = (UInt32)node.Gid * 4;
+ if (offset < _gids.Size())
+ prop = (UInt32)Get32(_gids + offset);
+ }
}
else
{
- UInt32 offset = node.Gid * 4;
- if (offset < _gids.Size())
- prop = (UInt32)Get32(_gids + offset);
+ const UInt32 offset = (UInt32)node.Gid * 4;
+ if (offset < _uids.Size())
+ prop = (UInt32)Get32(_uids + offset);
}
break;
}
- */
/*
case kpidLinks:
if (_h.Major >= 3 && node.Type != kType_FILE)
@@ -2128,7 +2139,7 @@ HRESULT CHandler::ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize)
packBlockSize != _cachedPackBlockSize)
{
ClearCache();
- RINOK(_stream->Seek(blockOffset, STREAM_SEEK_SET, NULL));
+ RINOK(Seek2(blockOffset));
_limitedInStreamSpec->Init(packBlockSize);
if (compressed)
diff --git a/CPP/7zip/Archive/StdAfx.h b/CPP/7zip/Archive/StdAfx.h
index 1cbd7fea..1cbd7fea 100644..100755
--- a/CPP/7zip/Archive/StdAfx.h
+++ b/CPP/7zip/Archive/StdAfx.h
diff --git a/CPP/7zip/Archive/SwfHandler.cpp b/CPP/7zip/Archive/SwfHandler.cpp
index a5ff1877..a5ff1877 100644..100755
--- a/CPP/7zip/Archive/SwfHandler.cpp
+++ b/CPP/7zip/Archive/SwfHandler.cpp
diff --git a/CPP/7zip/Archive/Tar/StdAfx.h b/CPP/7zip/Archive/Tar/StdAfx.h
index 2854ff3e..2854ff3e 100644..100755
--- a/CPP/7zip/Archive/Tar/StdAfx.h
+++ b/CPP/7zip/Archive/Tar/StdAfx.h
diff --git a/CPP/7zip/Archive/Tar/TarHandler.cpp b/CPP/7zip/Archive/Tar/TarHandler.cpp
index 2f23dd85..bd04bd7d 100644..100755
--- a/CPP/7zip/Archive/Tar/TarHandler.cpp
+++ b/CPP/7zip/Archive/Tar/TarHandler.cpp
@@ -36,22 +36,34 @@ static const Byte kProps[] =
kpidSize,
kpidPackSize,
kpidMTime,
+ kpidCTime,
+ kpidATime,
kpidPosixAttrib,
kpidUser,
kpidGroup,
+ kpidUserId,
+ kpidGroupId,
kpidSymLink,
kpidHardLink,
- kpidCharacts
- // kpidLinkType
+ kpidCharacts,
+ kpidComment
+ , kpidDeviceMajor
+ , kpidDeviceMinor
+ // , kpidDevice
+ // , kpidHeadersSize // for debug
+ // , kpidOffset // for debug
};
static const Byte kArcProps[] =
{
kpidHeadersSize,
kpidCodePage,
- kpidCharacts
+ kpidCharacts,
+ kpidComment
};
+static const char *k_Characts_Prefix = "PREFIX";
+
IMP_IInArchive_Props
IMP_IInArchive_ArcProps
@@ -60,14 +72,14 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
NCOM::CPropVariant prop;
switch (propID)
{
- case kpidPhySize: if (_phySizeDefined) prop = _phySize; break;
- case kpidHeadersSize: if (_phySizeDefined) prop = _headersSize; break;
+ case kpidPhySize: if (_arc._phySize_Defined) prop = _arc._phySize; break;
+ case kpidHeadersSize: if (_arc._phySize_Defined) prop = _arc._headersSize; break;
case kpidErrorFlags:
{
UInt32 flags = 0;
if (!_isArc)
flags |= kpv_ErrorFlags_IsNotArc;
- else switch (_error)
+ else switch (_arc._error)
{
case k_ErrorType_UnexpectedEnd: flags = kpv_ErrorFlags_UnexpectedEnd; break;
case k_ErrorType_Corrupted: flags = kpv_ErrorFlags_HeadersError; break;
@@ -82,7 +94,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
case kpidWarningFlags:
{
- if (_warning)
+ if (_arc._is_Warning)
prop = kpv_ErrorFlags_HeadersError;
break;
}
@@ -107,37 +119,38 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
case kpidCharacts:
{
- prop = _encodingCharacts.GetCharactsString();
+ AString s;
+ if (_arc._are_Gnu) s.Add_OptSpaced("GNU");
+ if (_arc._are_Posix) s.Add_OptSpaced("POSIX");
+ if (_arc._are_Pax_Items) s.Add_OptSpaced("PAX_ITEM");
+ if (_arc._pathPrefix_WasUsed) s.Add_OptSpaced(k_Characts_Prefix);
+ if (_arc._are_LongName) s.Add_OptSpaced("LongName");
+ if (_arc._are_LongLink) s.Add_OptSpaced("LongLink");
+ if (_arc._are_Pax) s.Add_OptSpaced("PAX");
+ if (_arc._are_pax_path) s.Add_OptSpaced("path");
+ if (_arc._are_pax_link) s.Add_OptSpaced("linkpath");
+ if (_arc._are_mtime) s.Add_OptSpaced("mtime");
+ if (_arc._are_atime) s.Add_OptSpaced("atime");
+ if (_arc._are_ctime) s.Add_OptSpaced("ctime");
+ if (_arc._is_PaxGlobal_Error) s.Add_OptSpaced("PAX_GLOBAL_ERROR");
+ s.Add_OptSpaced(_encodingCharacts.GetCharactsString());
+ prop = s;
break;
}
- }
- prop.Detach(value);
- return S_OK;
-}
-HRESULT CHandler::ReadItem2(ISequentialInStream *stream, bool &filled, CItemEx &item)
-{
- item.HeaderPos = _phySize;
- EErrorType error;
- HRESULT res = ReadItem(stream, filled, item, error);
- if (error == k_ErrorType_Warning)
- _warning = true;
- else if (error != k_ErrorType_OK)
- _error = error;
- RINOK(res);
- if (filled)
- {
- /*
- if (item.IsSparse())
- _isSparse = true;
- */
- if (item.IsPaxExtendedHeader())
- _thereIsPaxExtendedHeader = true;
- if (item.IsThereWarning())
- _warning = true;
+ case kpidComment:
+ {
+ if (_arc.PaxGlobal_Defined)
+ {
+ AString s;
+ _arc.PaxGlobal.Print_To_String(s);
+ if (!s.IsEmpty())
+ prop = s;
+ }
+ break;
+ }
}
- _phySize += item.HeaderSize;
- _headersSize += item.HeaderSize;
+ prop.Detach(value);
return S_OK;
}
@@ -199,16 +212,20 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));
}
- _phySizeDefined = true;
+ _arc._phySize_Defined = true;
// bool utf8_OK = true;
+ _arc.SeqStream = stream;
+ _arc.InStream = stream;
+ _arc.OpenCallback = callback;
+
+ CItemEx item;
for (;;)
{
- CItemEx item;
- bool filled;
- RINOK(ReadItem2(stream, filled, item));
- if (!filled)
+ _arc.NumFiles = _items.Size();
+ RINOK(_arc.ReadItem(item));
+ if (!_arc.filled)
break;
_isArc = true;
@@ -228,10 +245,10 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
_items.Add(item);
- RINOK(stream->Seek((Int64)item.GetPackSizeAligned(), STREAM_SEEK_CUR, &_phySize));
- if (_phySize > endPos)
+ RINOK(stream->Seek((Int64)item.Get_PackSize_Aligned(), STREAM_SEEK_CUR, &_arc._phySize));
+ if (_arc._phySize > endPos)
{
- _error = k_ErrorType_UnexpectedEnd;
+ _arc._error = k_ErrorType_UnexpectedEnd;
break;
}
/*
@@ -241,6 +258,7 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
break;
}
*/
+ /*
if (callback)
{
if (_items.Size() == 1)
@@ -249,10 +267,11 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
}
if ((_items.Size() & 0x3FF) == 0)
{
- UInt64 numFiles = _items.Size();
+ const UInt64 numFiles = _items.Size();
RINOK(callback->SetCompleted(&numFiles, &_phySize));
}
}
+ */
}
/*
@@ -266,7 +285,7 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
if (_items.Size() == 0)
{
- if (_error != k_ErrorType_OK)
+ if (_arc._error != k_ErrorType_OK)
{
_isArc = false;
return S_FALSE;
@@ -294,6 +313,7 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *openArchiveCallback)
{
COM_TRY_BEGIN
+ // for (int i = 0; i < 10; i++) // for debug
{
Close();
RINOK(Open2(stream, openArchiveCallback));
@@ -314,16 +334,11 @@ STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream)
STDMETHODIMP CHandler::Close()
{
_isArc = false;
- _warning = false;
- _error = k_ErrorType_OK;
- _phySizeDefined = false;
- _phySize = 0;
- _headersSize = 0;
+ _arc.Clear();
+
_curIndex = 0;
_latestIsRead = false;
- // _isSparse = false;
- _thereIsPaxExtendedHeader = false;
_encodingCharacts.Clear();
_items.Clear();
_seqStream.Release();
@@ -351,12 +366,12 @@ HRESULT CHandler::SkipTo(UInt32 index)
{
if (_latestIsRead)
{
- UInt64 packSize = _latestItem.GetPackSizeAligned();
+ const UInt64 packSize = _latestItem.Get_PackSize_Aligned();
RINOK(copyCoderSpec->Code(_seqStream, NULL, &packSize, &packSize, NULL));
- _phySize += copyCoderSpec->TotalSize;
+ _arc._phySize += copyCoderSpec->TotalSize;
if (copyCoderSpec->TotalSize != packSize)
{
- _error = k_ErrorType_UnexpectedEnd;
+ _arc._error = k_ErrorType_UnexpectedEnd;
return S_FALSE;
}
_latestIsRead = false;
@@ -364,11 +379,12 @@ HRESULT CHandler::SkipTo(UInt32 index)
}
else
{
- bool filled;
- RINOK(ReadItem2(_seqStream, filled, _latestItem));
- if (!filled)
+ _arc.SeqStream = _seqStream;
+ _arc.InStream = NULL;
+ RINOK(_arc.ReadItem(_latestItem));
+ if (!_arc.filled)
{
- _phySizeDefined = true;
+ _arc._phySize_Defined = true;
return E_INVALIDARG;
}
_latestIsRead = true;
@@ -390,6 +406,69 @@ void CHandler::TarStringToUnicode(const AString &s, NWindows::NCOM::CPropVariant
prop = dest;
}
+
+static void PaxTimeToProp(const CPaxTime &pt, NWindows::NCOM::CPropVariant &prop)
+{
+ UInt64 v;
+ if (!NTime::UnixTime64_To_FileTime64(pt.Sec, v))
+ return;
+ if (pt.Ns != 0)
+ v += pt.Ns / 100;
+ FILETIME ft;
+ ft.dwLowDateTime = (DWORD)v;
+ ft.dwHighDateTime = (DWORD)(v >> 32);
+ prop.SetAsTimeFrom_FT_Prec_Ns100(ft,
+ k_PropVar_TimePrec_Base + pt.NumDigits, pt.Ns % 100);
+}
+
+
+#define ValToHex(t) ((char)(((t) < 10) ? ('0' + (t)) : ('a' + ((t) - 10))))
+
+static void AddByteToHex2(unsigned val, AString &s)
+{
+ unsigned t;
+ t = val >> 4;
+ s += ValToHex(t);
+ t = val & 0xF;
+ s += ValToHex(t);
+}
+
+static void AddSpecCharToString(const char c, AString &s)
+{
+ if ((Byte)c <= 0x20 || (Byte)c > 127)
+ {
+ s += '[';
+ AddByteToHex2((Byte)(c), s);
+ s += ']';
+ }
+ else
+ s += c;
+}
+
+static void AddSpecUInt64(AString &s, const char *name, UInt64 v)
+{
+ if (v != 0)
+ {
+ s.Add_OptSpaced(name);
+ if (v > 1)
+ {
+ s += ':';
+ s.Add_UInt64(v);
+ }
+ }
+}
+
+static void AddSpecBools(AString &s, const char *name, bool b1, bool b2)
+{
+ if (b1)
+ {
+ s.Add_OptSpaced(name);
+ if (b2)
+ s += '*';
+ }
+}
+
+
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
@@ -413,49 +492,189 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{
case kpidPath: TarStringToUnicode(item->Name, prop, true); break;
case kpidIsDir: prop = item->IsDir(); break;
- case kpidSize: prop = item->GetUnpackSize(); break;
- case kpidPackSize: prop = item->GetPackSizeAligned(); break;
+ case kpidSize: prop = item->Get_UnpackSize(); break;
+ case kpidPackSize: prop = item->Get_PackSize_Aligned(); break;
case kpidMTime:
- if (item->MTime != 0)
+ {
+ /*
+ // for debug:
+ PropVariant_SetFrom_UnixTime(prop, 1 << 30);
+ prop.wReserved1 = k_PropVar_TimePrec_Base + 1;
+ prop.wReserved2 = 12;
+ break;
+ */
+
+ if (item->PaxTimes.MTime.IsDefined())
+ PaxTimeToProp(item->PaxTimes.MTime, prop);
+ else
+ // if (item->MTime != 0)
{
+ // we allow (item->MTime == 0)
FILETIME ft;
- if (NTime::UnixTime64ToFileTime(item->MTime, ft))
- prop = ft;
+ if (NTime::UnixTime64_To_FileTime(item->MTime, ft))
+ {
+ unsigned prec = k_PropVar_TimePrec_Unix;
+ if (item->MTime_IsBin)
+ {
+ /* we report here that it's Int64-UnixTime
+ instead of basic UInt32-UnixTime range */
+ prec = k_PropVar_TimePrec_Base;
+ }
+ prop.SetAsTimeFrom_FT_Prec(ft, prec);
+ }
}
break;
+ }
+ case kpidATime:
+ if (item->PaxTimes.ATime.IsDefined())
+ PaxTimeToProp(item->PaxTimes.ATime, prop);
+ break;
+ case kpidCTime:
+ if (item->PaxTimes.CTime.IsDefined())
+ PaxTimeToProp(item->PaxTimes.CTime, prop);
+ break;
case kpidPosixAttrib: prop = item->Get_Combined_Mode(); break;
- case kpidUser: TarStringToUnicode(item->User, prop); break;
- case kpidGroup: TarStringToUnicode(item->Group, prop); break;
- case kpidSymLink: if (item->LinkFlag == NFileHeader::NLinkFlag::kSymLink && !item->LinkName.IsEmpty()) TarStringToUnicode(item->LinkName, prop); break;
- case kpidHardLink: if (item->LinkFlag == NFileHeader::NLinkFlag::kHardLink && !item->LinkName.IsEmpty()) TarStringToUnicode(item->LinkName, prop); break;
- // case kpidLinkType: prop = (int)item->LinkFlag; break;
+
+ case kpidUser:
+ if (!item->User.IsEmpty())
+ TarStringToUnicode(item->User, prop);
+ break;
+ case kpidGroup:
+ if (!item->Group.IsEmpty())
+ TarStringToUnicode(item->Group, prop);
+ break;
+
+ case kpidUserId:
+ // if (item->UID != 0)
+ prop = (UInt32)item->UID;
+ break;
+ case kpidGroupId:
+ // if (item->GID != 0)
+ prop = (UInt32)item->GID;
+ break;
+
+ case kpidDeviceMajor:
+ if (item->DeviceMajor_Defined)
+ // if (item->DeviceMajor != 0)
+ prop = (UInt32)item->DeviceMajor;
+ break;
+
+ case kpidDeviceMinor:
+ if (item->DeviceMinor_Defined)
+ // if (item->DeviceMinor != 0)
+ prop = (UInt32)item->DeviceMinor;
+ break;
+ /*
+ case kpidDevice:
+ if (item->DeviceMajor_Defined)
+ if (item->DeviceMinor_Defined)
+ prop = (UInt64)MY_dev_makedev(item->DeviceMajor, item->DeviceMinor);
+ break;
+ */
+
+ case kpidSymLink:
+ if (item->Is_SymLink())
+ if (!item->LinkName.IsEmpty())
+ TarStringToUnicode(item->LinkName, prop);
+ break;
+ case kpidHardLink:
+ if (item->Is_HardLink())
+ if (!item->LinkName.IsEmpty())
+ TarStringToUnicode(item->LinkName, prop);
+ break;
+
case kpidCharacts:
{
- AString s = item->EncodingCharacts.GetCharactsString();
- if (item->IsThereWarning())
+ AString s;
{
s.Add_Space_if_NotEmpty();
- s += "HEADER_ERROR";
+ AddSpecCharToString(item->LinkFlag, s);
}
- prop = s;
+ if (item->IsMagic_GNU())
+ s.Add_OptSpaced("GNU");
+ else if (item->IsMagic_Posix_ustar_00())
+ s.Add_OptSpaced("POSIX");
+ else
+ {
+ s.Add_Space_if_NotEmpty();
+ for (unsigned i = 0; i < sizeof(item->Magic); i++)
+ AddSpecCharToString(item->Magic[i], s);
+ }
+
+ if (item->IsSignedChecksum)
+ s.Add_OptSpaced("SignedChecksum");
+
+ if (item->Prefix_WasUsed)
+ s.Add_OptSpaced(k_Characts_Prefix);
+
+ s.Add_OptSpaced(item->EncodingCharacts.GetCharactsString());
+
+ // AddSpecUInt64(s, "LongName", item->Num_LongName_Records);
+ // AddSpecUInt64(s, "LongLink", item->Num_LongLink_Records);
+ AddSpecBools(s, "LongName", item->LongName_WasUsed, item->LongName_WasUsed_2);
+ AddSpecBools(s, "LongLink", item->LongLink_WasUsed, item->LongLink_WasUsed_2);
+
+ if (item->MTime_IsBin)
+ s.Add_OptSpaced("bin_mtime");
+ if (item->PackSize_IsBin)
+ s.Add_OptSpaced("bin_psize");
+ if (item->Size_IsBin)
+ s.Add_OptSpaced("bin_size");
+
+ AddSpecUInt64(s, "PAX", item->Num_Pax_Records);
+
+ if (item->PaxTimes.MTime.IsDefined()) s.Add_OptSpaced("mtime");
+ if (item->PaxTimes.ATime.IsDefined()) s.Add_OptSpaced("atime");
+ if (item->PaxTimes.CTime.IsDefined()) s.Add_OptSpaced("ctime");
+
+ if (item->pax_path_WasUsed)
+ s.Add_OptSpaced("pax_path");
+ if (item->pax_link_WasUsed)
+ s.Add_OptSpaced("pax_linkpath");
+ if (item->pax_size_WasUsed)
+ s.Add_OptSpaced("pax_size");
+
+ if (item->IsThereWarning())
+ s.Add_OptSpaced("WARNING");
+ if (item->HeaderError)
+ s.Add_OptSpaced("ERROR");
+ if (item->Pax_Error)
+ s.Add_OptSpaced("PAX_error");
+ if (!item->PaxExtra.RawLines.IsEmpty())
+ s.Add_OptSpaced("PAX_unsupported_line");
+ if (item->Pax_Overflow)
+ s.Add_OptSpaced("PAX_overflow");
+ if (!s.IsEmpty())
+ prop = s;
break;
}
+ case kpidComment:
+ {
+ AString s;
+ item->PaxExtra.Print_To_String(s);
+ if (!s.IsEmpty())
+ prop = s;
+ break;
+ }
+ // case kpidHeadersSize: prop = item->HeaderSize; break; // for debug
+ // case kpidOffset: prop = item->HeaderPos; break; // for debug
}
prop.Detach(value);
return S_OK;
COM_TRY_END
}
+
HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems,
Int32 testMode, IArchiveExtractCallback *extractCallback)
{
COM_TRY_BEGIN
ISequentialInStream *stream = _seqStream;
- bool seqMode = (_stream == NULL);
+ const bool seqMode = (_stream == NULL);
if (!seqMode)
stream = _stream;
- bool allFilesMode = (numItems == (UInt32)(Int32)-1);
+ const bool allFilesMode = (numItems == (UInt32)(Int32)-1);
if (allFilesMode)
numItems = _items.Size();
if (_stream && numItems == 0)
@@ -463,7 +682,7 @@ HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems,
UInt64 totalSize = 0;
UInt32 i;
for (i = 0; i < numItems; i++)
- totalSize += _items[allFilesMode ? i : indices[i]].GetUnpackSize();
+ totalSize += _items[allFilesMode ? i : indices[i]].Get_UnpackSize();
extractCallback->SetTotal(totalSize);
UInt64 totalPackSize;
@@ -503,9 +722,9 @@ HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems,
item = &_items[index];
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
- UInt64 unpackSize = item->GetUnpackSize();
+ const UInt64 unpackSize = item->Get_UnpackSize();
totalSize += unpackSize;
- totalPackSize += item->GetPackSizeAligned();
+ totalPackSize += item->Get_PackSize_Aligned();
if (item->IsDir())
{
RINOK(extractCallback->PrepareOperation(askMode));
@@ -539,7 +758,7 @@ HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems,
Int32 opRes = NExtract::NOperationResult::kOK;
CMyComPtr<ISequentialInStream> inStream2;
- if (!item->IsSparse())
+ if (!item->Is_Sparse())
inStream2 = inStream;
else
{
@@ -549,7 +768,7 @@ HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems,
}
{
- if (item->IsSymLink())
+ if (item->Is_SymLink())
{
RINOK(WriteStream(outStreamSpec, (const char *)item->LinkName, item->LinkName.Len()));
}
@@ -557,9 +776,9 @@ HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems,
{
if (!seqMode)
{
- RINOK(_stream->Seek((Int64)item->GetDataPosition(), STREAM_SEEK_SET, NULL));
+ RINOK(_stream->Seek((Int64)item->Get_DataPos(), STREAM_SEEK_SET, NULL));
}
- streamSpec->Init(item->GetPackSizeAligned());
+ streamSpec->Init(item->Get_PackSize_Aligned());
RINOK(copyCoder->Code(inStream2, outStream, NULL, NULL, progress));
}
if (outStreamSpec->GetRem() != 0)
@@ -628,7 +847,7 @@ STDMETHODIMP CSparseStream::Read(void *data, UInt32 size, UInt32 *processedSize)
unsigned left = 0, right = item.SparseBlocks.Size();
for (;;)
{
- unsigned mid = (left + right) / 2;
+ const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2);
if (mid == left)
break;
if (_virtPos < item.SparseBlocks[mid].Offset)
@@ -648,7 +867,7 @@ STDMETHODIMP CSparseStream::Read(void *data, UInt32 size, UInt32 *processedSize)
UInt64 phyPos = PhyOffsets[left] + relat;
if (_needStartSeek || _phyPos != phyPos)
{
- RINOK(Handler->_stream->Seek((Int64)(item.GetDataPosition() + phyPos), STREAM_SEEK_SET, NULL));
+ RINOK(Handler->_stream->Seek((Int64)(item.Get_DataPos() + phyPos), STREAM_SEEK_SET, NULL));
_needStartSeek = false;
_phyPos = phyPos;
}
@@ -698,7 +917,7 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
const CItemEx &item = _items[index];
- if (item.IsSparse())
+ if (item.Is_Sparse())
{
CSparseStream *streamSpec = new CSparseStream;
CMyComPtr<IInStream> streamTemp = streamSpec;
@@ -718,24 +937,30 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
return S_OK;
}
- if (item.IsSymLink())
+ if (item.Is_SymLink())
{
Create_BufInStream_WithReference((const Byte *)(const char *)item.LinkName, item.LinkName.Len(), (IInArchive *)this, stream);
return S_OK;
}
- return CreateLimitedInStream(_stream, item.GetDataPosition(), item.PackSize, stream);
+ return CreateLimitedInStream(_stream, item.Get_DataPos(), item.PackSize, stream);
COM_TRY_END
}
+
void CHandler::Init()
{
_forceCodePage = false;
_curCodePage = _specifiedCodePage = CP_UTF8; // CP_OEMCP;
- _thereIsPaxExtendedHeader = false;
+ _posixMode = false;
+ _posixMode_WasForced = false;
+ // TimeOptions.Clear();
+ _handlerTimeOptions.Init();
+ // _handlerTimeOptions.Write_MTime.Val = true; // it's default already
}
+
STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)
{
Init();
@@ -768,8 +993,54 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
else if (name.IsPrefixedBy_Ascii_NoCase("memuse"))
{
}
+ else if (name.IsEqualTo("m"))
+ {
+ if (prop.vt != VT_BSTR)
+ return E_INVALIDARG;
+ const UString s = prop.bstrVal;
+ if (s.IsEqualTo_Ascii_NoCase("pax") ||
+ s.IsEqualTo_Ascii_NoCase("posix"))
+ _posixMode = true;
+ else if (s.IsEqualTo_Ascii_NoCase("gnu"))
+ _posixMode = false;
+ else
+ return E_INVALIDARG;
+ _posixMode_WasForced = true;
+ }
else
+ {
+ /*
+ if (name.IsPrefixedBy_Ascii_NoCase("td"))
+ {
+ name.Delete(0, 3);
+ if (prop.vt == VT_EMPTY)
+ {
+ if (name.IsEqualTo_Ascii_NoCase("n"))
+ {
+ // TimeOptions.UseNativeDigits = true;
+ }
+ else if (name.IsEqualTo_Ascii_NoCase("r"))
+ {
+ // TimeOptions.RemoveZeroDigits = true;
+ }
+ else
+ return E_INVALIDARG;
+ }
+ else
+ {
+ UInt32 numTimeDigits = 0;
+ RINOK(ParsePropToUInt32(name, prop, numTimeDigits));
+ TimeOptions.NumDigits_WasForced = true;
+ TimeOptions.NumDigits = numTimeDigits;
+ }
+ }
+ */
+ bool processed = false;
+ RINOK(_handlerTimeOptions.Parse(name, prop, processed));
+ if (processed)
+ continue;
return E_INVALIDARG;
+ }
}
return S_OK;
}
diff --git a/CPP/7zip/Archive/Tar/TarHandler.h b/CPP/7zip/Archive/Tar/TarHandler.h
index 4834c2a7..44a99809 100644..100755
--- a/CPP/7zip/Archive/Tar/TarHandler.h
+++ b/CPP/7zip/Archive/Tar/TarHandler.h
@@ -9,7 +9,7 @@
#include "../../Compress/CopyCoder.h"
-#include "../IArchive.h"
+#include "../Common/HandlerOut.h"
#include "TarIn.h"
@@ -29,31 +29,26 @@ public:
CMyComPtr<IInStream> _stream;
CMyComPtr<ISequentialInStream> _seqStream;
private:
- UInt32 _curIndex;
- bool _latestIsRead;
- CItemEx _latestItem;
-
- UInt64 _phySize;
- UInt64 _headersSize;
- bool _phySizeDefined;
- EErrorType _error;
- bool _warning;
bool _isArc;
-
- // bool _isSparse;
- bool _thereIsPaxExtendedHeader;
-
+ bool _posixMode_WasForced;
+ bool _posixMode;
bool _forceCodePage;
UInt32 _specifiedCodePage;
UInt32 _curCodePage;
UInt32 _openCodePage;
-
+ // CTimeOptions TimeOptions;
+ CHandlerTimeOptions _handlerTimeOptions;
CEncodingCharacts _encodingCharacts;
+ UInt32 _curIndex;
+ bool _latestIsRead;
+ CItemEx _latestItem;
+
+ CArchive _arc;
+
NCompress::CCopyCoder *copyCoderSpec;
CMyComPtr<ICompressCoder> copyCoder;
- HRESULT ReadItem2(ISequentialInStream *stream, bool &filled, CItemEx &itemInfo);
HRESULT Open2(IInStream *stream, IArchiveOpenCallback *callback);
HRESULT SkipTo(UInt32 index);
void TarStringToUnicode(const AString &s, NWindows::NCOM::CPropVariant &prop, bool toOs = false) const;
diff --git a/CPP/7zip/Archive/Tar/TarHandlerOut.cpp b/CPP/7zip/Archive/Tar/TarHandlerOut.cpp
index 5ddb4b24..53255e4c 100644..100755
--- a/CPP/7zip/Archive/Tar/TarHandlerOut.cpp
+++ b/CPP/7zip/Archive/Tar/TarHandlerOut.cpp
@@ -2,15 +2,16 @@
#include "StdAfx.h"
+// #include <stdio.h>
+
#include "../../../Common/ComTry.h"
-#include "../../../Common/Defs.h"
#include "../../../Common/MyLinux.h"
#include "../../../Common/StringConvert.h"
-#include "../../../Common/UTFConvert.h"
-#include "../../../Windows/PropVariant.h"
#include "../../../Windows/TimeUtils.h"
+#include "../Common/ItemNameUtils.h"
+
#include "TarHandler.h"
#include "TarUpdate.h"
@@ -21,10 +22,35 @@ namespace NTar {
STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
{
- *type = NFileTimeType::kUnix;
+ UInt32 t = NFileTimeType::kUnix;
+ const UInt32 prec = _handlerTimeOptions.Prec;
+ if (prec != (UInt32)(Int32)-1)
+ {
+ t = NFileTimeType::kWindows;
+ if (prec == k_PropVar_TimePrec_0 ||
+ prec == k_PropVar_TimePrec_100ns)
+ t = NFileTimeType::kWindows;
+ else if (prec == k_PropVar_TimePrec_HighPrec)
+ t = k_PropVar_TimePrec_1ns;
+ else if (prec >= k_PropVar_TimePrec_Base)
+ t = prec;
+ }
+ // 7-Zip before 22.00 fails, if unknown typeType.
+ *type = t;
return S_OK;
}
+
+void Get_AString_From_UString(const UString &s, AString &res,
+ UINT codePage, unsigned utfFlags)
+{
+ if (codePage == CP_UTF8)
+ ConvertUnicodeToUTF8_Flags(s, res, utfFlags);
+ else
+ UnicodeStringToMultiByte2(res, s, codePage);
+}
+
+
HRESULT GetPropString(IArchiveUpdateCallback *callback, UInt32 index, PROPID propId, AString &res,
UINT codePage, unsigned utfFlags, bool convertSlash)
{
@@ -36,14 +62,7 @@ HRESULT GetPropString(IArchiveUpdateCallback *callback, UInt32 index, PROPID pro
UString s = prop.bstrVal;
if (convertSlash)
NItemName::ReplaceSlashes_OsToUnix(s);
-
- if (codePage == CP_UTF8)
- {
- ConvertUnicodeToUTF8_Flags(s, res, utfFlags);
- // if (!ConvertUnicodeToUTF8(s, res)) // return E_INVALIDARG;
- }
- else
- UnicodeStringToMultiByte2(res, s, codePage);
+ Get_AString_From_UString(s, res, codePage, utfFlags);
}
else if (prop.vt != VT_EMPTY)
return E_INVALIDARG;
@@ -70,12 +89,106 @@ static int CompareUpdateItems(void *const *p1, void *const *p2, void *)
}
+static HRESULT GetTime(UInt32 i, UInt32 pid, IArchiveUpdateCallback *callback,
+ CPaxTime &pt)
+{
+ pt.Clear();
+ NCOM::CPropVariant prop;
+ RINOK(callback->GetProperty(i, pid, &prop));
+ return Prop_To_PaxTime(prop, pt);
+}
+
+
+/*
+static HRESULT GetDevice(IArchiveUpdateCallback *callback, UInt32 i,
+ UInt32 &majo, UInt32 &mino, bool &majo_defined, bool &mino_defined)
+{
+ NWindows::NCOM::CPropVariant prop;
+ RINOK(callback->GetProperty(i, kpidDevice, &prop));
+ if (prop.vt == VT_EMPTY)
+ return S_OK;
+ if (prop.vt != VT_UI8)
+ return E_INVALIDARG;
+ {
+ const UInt64 v = prop.uhVal.QuadPart;
+ majo = MY_dev_major(v);
+ mino = MY_dev_minor(v);
+ majo_defined = true;
+ mino_defined = true;
+ }
+ return S_OK;
+}
+*/
+
+static HRESULT GetDevice(IArchiveUpdateCallback *callback, UInt32 i,
+ UInt32 pid, UInt32 &id, bool &defined)
+{
+ defined = false;
+ NWindows::NCOM::CPropVariant prop;
+ RINOK(callback->GetProperty(i, pid, &prop));
+ if (prop.vt == VT_EMPTY)
+ return S_OK;
+ if (prop.vt == VT_UI4)
+ {
+ id = prop.ulVal;
+ defined = true;
+ return S_OK;
+ }
+ return E_INVALIDARG;
+}
+
+
+static HRESULT GetUser(IArchiveUpdateCallback *callback, UInt32 i,
+ UInt32 pidName, UInt32 pidId, AString &name, UInt32 &id,
+ UINT codePage, unsigned utfFlags)
+{
+ // printf("\ncallback->GetProperty(i, pidId, &prop))\n");
+
+ bool isSet = false;
+ {
+ NWindows::NCOM::CPropVariant prop;
+ RINOK(callback->GetProperty(i, pidId, &prop));
+ if (prop.vt == VT_UI4)
+ {
+ isSet = true;
+ id = prop.ulVal;
+ // printf("\ncallback->GetProperty(i, pidId, &prop)); = %d \n", (unsigned)id);
+ name.Empty();
+ }
+ else if (prop.vt != VT_EMPTY)
+ return E_INVALIDARG;
+ }
+ {
+ NWindows::NCOM::CPropVariant prop;
+ RINOK(callback->GetProperty(i, pidName, &prop));
+ if (prop.vt == VT_BSTR)
+ {
+ const UString s = prop.bstrVal;
+ Get_AString_From_UString(s, name, codePage, utfFlags);
+ if (!isSet)
+ id = 0;
+ }
+ else if (prop.vt == VT_UI4)
+ {
+ id = prop.ulVal;
+ name.Empty();
+ }
+ else if (prop.vt != VT_EMPTY)
+ return E_INVALIDARG;
+ }
+ return S_OK;
+}
+
+
+
STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
IArchiveUpdateCallback *callback)
{
COM_TRY_BEGIN
- if ((_stream && (_error != k_ErrorType_OK || _warning /* || _isSparse */)) || _seqStream)
+ if ((_stream && (_arc._error != k_ErrorType_OK || _arc._is_Warning
+ /* || _isSparse */
+ )) || _seqStream)
return E_NOTIMPL;
CObjectVector<CUpdateItem> updateItems;
const UINT codePage = (_forceCodePage ? _specifiedCodePage : _openCodePage);
@@ -131,25 +244,30 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
else
ui.Mode = prop.ulVal;
// 21.07 : we clear high file type bits as GNU TAR.
- ui.Mode &= ~(UInt32)MY_LIN_S_IFMT;
+ // we will clear it later
+ // ui.Mode &= ~(UInt32)MY_LIN_S_IFMT;
}
- {
- NCOM::CPropVariant prop;
- RINOK(callback->GetProperty(i, kpidMTime, &prop));
- if (prop.vt == VT_EMPTY)
- ui.MTime = 0;
- else if (prop.vt != VT_FILETIME)
- return E_INVALIDARG;
- else
- ui.MTime = NTime::FileTimeToUnixTime64(prop.filetime);
- }
-
+ if (_handlerTimeOptions.Write_MTime.Val)
+ RINOK(GetTime(i, kpidMTime, callback, ui.PaxTimes.MTime))
+ if (_handlerTimeOptions.Write_ATime.Val)
+ RINOK(GetTime(i, kpidATime, callback, ui.PaxTimes.ATime))
+ if (_handlerTimeOptions.Write_CTime.Val)
+ RINOK(GetTime(i, kpidCTime, callback, ui.PaxTimes.CTime))
+
RINOK(GetPropString(callback, i, kpidPath, ui.Name, codePage, utfFlags, true));
if (ui.IsDir && !ui.Name.IsEmpty() && ui.Name.Back() != '/')
ui.Name += '/';
- RINOK(GetPropString(callback, i, kpidUser, ui.User, codePage, utfFlags, false));
- RINOK(GetPropString(callback, i, kpidGroup, ui.Group, codePage, utfFlags, false));
+ // ui.Name += '/'; // for debug
+
+ if (_posixMode)
+ {
+ RINOK(GetDevice(callback, i, kpidDeviceMajor, ui.DeviceMajor, ui.DeviceMajor_Defined));
+ RINOK(GetDevice(callback, i, kpidDeviceMinor, ui.DeviceMinor, ui.DeviceMinor_Defined));
+ }
+
+ RINOK(GetUser(callback, i, kpidUser, kpidUserId, ui.User, ui.UID, codePage, utfFlags));
+ RINOK(GetUser(callback, i, kpidGroup, kpidGroupId, ui.Group, ui.GID, codePage, utfFlags));
}
if (IntToBool(newData))
@@ -169,13 +287,44 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
updateItems.Add(ui);
}
- if (_thereIsPaxExtendedHeader)
+ if (_arc._are_Pax_Items)
{
- // we restore original order of files, if there is pax header block
+ // we restore original order of files, if there are pax items
updateItems.Sort(CompareUpdateItems, NULL);
}
+
+ CUpdateOptions options;
+
+ options.CodePage = codePage;
+ options.UtfFlags = utfFlags;
+ options.PosixMode = _posixMode;
+
+ options.Write_MTime = _handlerTimeOptions.Write_MTime;
+ options.Write_ATime = _handlerTimeOptions.Write_ATime;
+ options.Write_CTime = _handlerTimeOptions.Write_CTime;
- return UpdateArchive(_stream, outStream, _items, updateItems, codePage, utfFlags, callback);
+ // options.TimeOptions = TimeOptions;
+
+ const UInt32 prec = _handlerTimeOptions.Prec;
+ if (prec != (UInt32)(Int32)-1)
+ {
+ unsigned numDigits = 0;
+ if (prec == 0)
+ numDigits = 7;
+ else if (prec == k_PropVar_TimePrec_HighPrec
+ || prec >= k_PropVar_TimePrec_1ns)
+ numDigits = 9;
+ else if (prec >= k_PropVar_TimePrec_Base)
+ numDigits = prec - k_PropVar_TimePrec_Base;
+ options.TimeOptions.NumDigitsMax = numDigits;
+ // options.TimeOptions.RemoveZeroMode =
+ // k_PaxTimeMode_DontRemoveZero; // pure for debug
+ // k_PaxTimeMode_RemoveZero_if_PureSecondOnly; // optimized code
+ // k_PaxTimeMode_RemoveZero_Always; // original pax code
+ }
+
+ return UpdateArchive(_stream, outStream, _items, updateItems,
+ options, callback);
COM_TRY_END
}
diff --git a/CPP/7zip/Archive/Tar/TarHeader.cpp b/CPP/7zip/Archive/Tar/TarHeader.cpp
index 9c16c895..f1efddb5 100644..100755
--- a/CPP/7zip/Archive/Tar/TarHeader.cpp
+++ b/CPP/7zip/Archive/Tar/TarHeader.cpp
@@ -18,9 +18,82 @@ namespace NFileHeader {
// const char * const kGNUTar = "GNUtar "; // 7 chars and a null
// const char * const kEmpty = "\0\0\0\0\0\0\0\0";
// 7-Zip used kUsTar_00 before 21.07:
- // const char kUsTar_00[8] = { 'u', 's', 't', 'a', 'r', 0, '0', '0' } ;
+ const char k_Posix_ustar_00[8] = { 'u', 's', 't', 'a', 'r', 0, '0', '0' } ;
// GNU TAR uses such header:
- const char kUsTar_GNU[8] = { 'u', 's', 't', 'a', 'r', ' ', ' ', 0 } ;
+ const char k_GNU_ustar__[8] = { 'u', 's', 't', 'a', 'r', ' ', ' ', 0 } ;
}
+/*
+pre-POSIX.1-1988 (i.e. v7) tar header:
+-----
+Link indicator:
+'0' or 0 : Normal file
+'1' : Hard link
+'2' : Symbolic link
+Some pre-POSIX.1-1988 tar implementations indicated a directory by having
+a trailing slash (/) in the name.
+
+Numeric values : octal with leading zeroes.
+For historical reasons, a final NUL or space character should also be used.
+Thus only 11 octal digits can be stored from 12 bytes field.
+
+2001 star : introduced a base-256 coding that is indicated by
+setting the high-order bit of the leftmost byte of a numeric field.
+GNU-tar and BSD-tar followed this idea.
+
+versions of tar from before the first POSIX standard from 1988
+pad the values with spaces instead of zeroes.
+
+UStar
+-----
+UStar (Unix Standard TAR) : POSIX IEEE P1003.1 : 1988.
+ 257 signature: "ustar", 0, "00"
+ 265 32 Owner user name
+ 297 32 Owner group name
+ 329 8 Device major number
+ 337 8 Device minor number
+ 345 155 Filename prefix
+
+POSIX.1-2001/pax
+----
+format is known as extended tar format or pax format
+vendor-tagged vendor-specific enhancements.
+tags Defined by the POSIX standard:
+ atime, mtime, path, linkpath, uname, gname, size, uid, gid, ...
+
+
+PAX EXTENSION
+-----------
+Hard links
+A further difference from the ustar header block is that data blocks
+for files of typeflag 1 (hard link) may be included,
+which means that the size field may be greater than zero.
+Archives created by pax -o linkdata shall include these data
+blocks with the hard links.
+*
+
+compatiblity
+------------
+ 7-Zip 16.03 supports "PaxHeader/"
+ 7-Zip 20.01 supports "PaxHeaders.X/" with optional "./"
+ 7-Zip 21.02 supports "@PaxHeader" with optional "./" "./"
+
+ GNU tar --format=posix uses "PaxHeaders/" in folder of file
+
+
+GNU TAR format
+==============
+v7 - Unix V7
+oldgnu - GNU tar <=1.12 : writes zero in last character in name
+gnu - GNU tar 1.13 : doesn't write zero in last character in name
+ as 7-zip 21.07
+ustar - POSIX.1-1988
+posix (pax) - POSIX.1-2001
+
+ gnu tar:
+ if (S_ISCHR (st->stat.st_mode) || S_ISBLK (st->stat.st_mode)) {
+ major_t devmajor = major (st->stat.st_rdev);
+ minor_t devminor = minor (st->stat.st_rdev); }
+*/
+
}}}
diff --git a/CPP/7zip/Archive/Tar/TarHeader.h b/CPP/7zip/Archive/Tar/TarHeader.h
index b0f0ec34..1af30935 100644..100755
--- a/CPP/7zip/Archive/Tar/TarHeader.h
+++ b/CPP/7zip/Archive/Tar/TarHeader.h
@@ -59,6 +59,9 @@ namespace NFileHeader
const char kGnu_LongName = 'L';
const char kSparse = 'S';
const char kLabel = 'V';
+ const char kPax = 'x'; // Extended header with meta data for the next file in the archive (POSIX.1-2001)
+ const char kPax_2 = 'X';
+ const char kGlobal = 'g'; // Global extended header with meta data (POSIX.1-2001)
const char kDumpDir = 'D'; /* GNUTYPE_DUMPDIR.
data: list of files created by the --incremental (-G) option
Each file name is preceded by either
@@ -66,6 +69,7 @@ namespace NFileHeader
- 'N' (file is a directory, or is not stored in the archive.)
Each file name is terminated by a null + an additional null after
the last file name. */
+ // 'A'-'Z' Vendor specific extensions (POSIX.1-1988)
}
extern const char * const kLongLink; // = "././@LongLink";
@@ -76,8 +80,8 @@ namespace NFileHeader
// extern const char * const kUsTar; // = "ustar"; // 5 chars
// extern const char * const kGNUTar; // = "GNUtar "; // 7 chars and a null
// extern const char * const kEmpty; // = "\0\0\0\0\0\0\0\0"
- // extern const char kUsTar_00[8];
- extern const char kUsTar_GNU[8];
+ extern const char k_Posix_ustar_00[8];
+ extern const char k_GNU_ustar__[8];
}
}
diff --git a/CPP/7zip/Archive/Tar/TarIn.cpp b/CPP/7zip/Archive/Tar/TarIn.cpp
index 58399d0c..4fd8c5b1 100644..100755
--- a/CPP/7zip/Archive/Tar/TarIn.cpp
+++ b/CPP/7zip/Archive/Tar/TarIn.cpp
@@ -12,6 +12,45 @@
#include "TarIn.h"
+#define NUM_UNROLL_BYTES (8 * 4)
+
+MY_NO_INLINE static bool IsBufNonZero(const void *data, size_t size);
+MY_NO_INLINE static bool IsBufNonZero(const void *data, size_t size)
+{
+ const Byte *p = (const Byte *)data;
+
+ for (; size != 0 && ((unsigned)(ptrdiff_t)p & (NUM_UNROLL_BYTES - 1)) != 0; size--)
+ if (*p++ != 0)
+ return true;
+
+ if (size >= NUM_UNROLL_BYTES)
+ {
+ const Byte *lim = p + size;
+ size &= (NUM_UNROLL_BYTES - 1);
+ lim -= size;
+ do
+ {
+ if (*(const UInt64 *)(const void *)(p ) != 0) return true;
+ if (*(const UInt64 *)(const void *)(p + 8 * 1) != 0) return true;
+ if (*(const UInt64 *)(const void *)(p + 8 * 2) != 0) return true;
+ if (*(const UInt64 *)(const void *)(p + 8 * 3) != 0) return true;
+ // if (*(const UInt32 *)(const void *)(p ) != 0) return true;
+ // if (*(const UInt32 *)(const void *)(p + 4 * 1) != 0) return true;
+ // if (*(const UInt32 *)(const void *)(p + 4 * 2) != 0) return true;
+ // if (*(const UInt32 *)(const void *)(p + 4 * 3) != 0) return true;
+ p += NUM_UNROLL_BYTES;
+ }
+ while (p != lim);
+ }
+
+ for (; size != 0; size--)
+ if (*p++ != 0)
+ return true;
+
+ return false;
+}
+
+
namespace NArchive {
namespace NTar {
@@ -41,10 +80,11 @@ static bool OctalToNumber(const char *srcString, unsigned size, UInt64 &res, boo
return (*end == ' ' || *end == 0);
}
-static bool OctalToNumber32(const char *srcString, unsigned size, UInt32 &res, bool allowEmpty = false)
+static bool OctalToNumber32(const char *srcString, UInt32 &res, bool allowEmpty = false)
{
+ const unsigned kSize = 8;
UInt64 res64;
- if (!OctalToNumber(srcString, size, res64, allowEmpty))
+ if (!OctalToNumber(srcString, kSize, res64, allowEmpty))
return false;
res = (UInt32)res64;
return (res64 <= 0xFFFFFFFF);
@@ -52,68 +92,61 @@ static bool OctalToNumber32(const char *srcString, unsigned size, UInt32 &res, b
#define RIF(x) { if (!(x)) return S_OK; }
-/*
-static bool IsEmptyData(const char *buf, size_t size)
-{
- for (unsigned i = 0; i < size; i++)
- if (buf[i] != 0)
- return false;
- return true;
-}
-*/
-
-static bool IsRecordLast(const char *buf)
-{
- for (unsigned i = 0; i < NFileHeader::kRecordSize; i++)
- if (buf[i] != 0)
- return false;
- return true;
-}
-
static void ReadString(const char *s, unsigned size, AString &result)
{
result.SetFrom_CalcLen(s, size);
}
-static bool ParseInt64(const char *p, Int64 &val)
+static bool ParseInt64(const char *p, Int64 &val, bool &isBin)
{
- UInt32 h = GetBe32(p);
+ const UInt32 h = GetBe32(p);
val = (Int64)GetBe64(p + 4);
+ isBin = true;
if (h == (UInt32)1 << 31)
return ((val >> 63) & 1) == 0;
if (h == (UInt32)(Int32)-1)
return ((val >> 63) & 1) != 0;
- UInt64 uv;
- bool res = OctalToNumber(p, 12, uv);
- val = (Int64)uv;
+ isBin = false;
+ UInt64 u;
+ const bool res = OctalToNumber(p, 12, u);
+ val = (Int64)u;
return res;
}
-static bool ParseInt64_MTime(const char *p, Int64 &val)
+static bool ParseInt64_MTime(const char *p, Int64 &val, bool &isBin)
{
// rare case tar : ZEROs in Docker-Windows TARs
// rare case tar : spaces
+ isBin = false;
if (GetUi32(p) != 0)
for (unsigned i = 0; i < 12; i++)
if (p[i] != ' ')
- return ParseInt64(p, val);
+ return ParseInt64(p, val, isBin);
val = 0;
return true;
}
-static bool ParseSize(const char *p, UInt64 &val)
+static bool ParseSize(const char *p, UInt64 &val, bool &isBin)
{
if (GetBe32(p) == (UInt32)1 << 31)
{
// GNU extension
+ isBin = true;
val = GetBe64(p + 4);
return ((val >> 63) & 1) == 0;
}
+ isBin = false;
return OctalToNumber(p, 12, val,
true // 20.03: allow empty size for 'V' Label entry
);
}
+static bool ParseSize(const char *p, UInt64 &val)
+{
+ bool isBin;
+ return ParseSize(p, val, isBin);
+}
+
#define CHECK(x) { if (!(x)) return k_IsArc_Res_NO; }
API_FUNC_IsArc IsArc_Tar(const Byte *p2, size_t size)
@@ -126,26 +159,27 @@ API_FUNC_IsArc IsArc_Tar(const Byte *p2, size_t size)
UInt32 mode;
// we allow empty Mode value for LongName prefix items
- CHECK(OctalToNumber32(p, 8, mode, true)); p += 8;
+ CHECK(OctalToNumber32(p, mode, true)); p += 8;
- // if (!OctalToNumber32(p, 8, item.UID)) item.UID = 0;
+ // if (!OctalToNumber32(p, item.UID)) item.UID = 0;
p += 8;
- // if (!OctalToNumber32(p, 8, item.GID)) item.GID = 0;
+ // if (!OctalToNumber32(p, item.GID)) item.GID = 0;
p += 8;
UInt64 packSize;
Int64 time;
UInt32 checkSum;
- CHECK(ParseSize(p, packSize)); p += 12;
- CHECK(ParseInt64_MTime(p, time)); p += 12;
- CHECK(OctalToNumber32(p, 8, checkSum));
+ bool isBin;
+ CHECK(ParseSize(p, packSize, isBin)); p += 12;
+ CHECK(ParseInt64_MTime(p, time, isBin)); p += 12;
+ CHECK(OctalToNumber32(p, checkSum));
return k_IsArc_Res_YES;
}
-static HRESULT GetNextItemReal(ISequentialInStream *stream, bool &filled, CItemEx &item, EErrorType &error)
+
+HRESULT CArchive::GetNextItemReal(CItemEx &item)
{
char buf[NFileHeader::kRecordSize];
- char *p = buf;
error = k_ErrorType_OK;
filled = false;
@@ -154,7 +188,7 @@ static HRESULT GetNextItemReal(ISequentialInStream *stream, bool &filled, CItemE
for (;;)
{
size_t processedSize = NFileHeader::kRecordSize;
- RINOK(ReadStream(stream, buf, &processedSize));
+ RINOK(ReadStream(SeqStream, buf, &processedSize));
if (processedSize == 0)
{
if (!thereAreEmptyRecords)
@@ -180,10 +214,14 @@ static HRESULT GetNextItemReal(ISequentialInStream *stream, bool &filled, CItemE
return S_OK;
}
- if (!IsRecordLast(buf))
+ if (IsBufNonZero(buf, NFileHeader::kRecordSize))
break;
item.HeaderSize += NFileHeader::kRecordSize;
thereAreEmptyRecords = true;
+ if (OpenCallback)
+ {
+ RINOK(Progress(item, 0));
+ }
}
if (thereAreEmptyRecords)
{
@@ -191,52 +229,69 @@ static HRESULT GetNextItemReal(ISequentialInStream *stream, bool &filled, CItemE
return S_OK;
}
+ char *p = buf;
+
error = k_ErrorType_Corrupted;
- ReadString(p, NFileHeader::kNameSize, item.Name); p += NFileHeader::kNameSize;
- item.NameCouldBeReduced =
+
+ // ReadString(p, NFileHeader::kNameSize, item.Name);
+ p += NFileHeader::kNameSize;
+
+ /*
+ item.Name_CouldBeReduced =
(item.Name.Len() == NFileHeader::kNameSize ||
item.Name.Len() == NFileHeader::kNameSize - 1);
+ */
// we allow empty Mode value for LongName prefix items
- RIF(OctalToNumber32(p, 8, item.Mode, true)); p += 8;
+ RIF(OctalToNumber32(p, item.Mode, true)); p += 8;
- if (!OctalToNumber32(p, 8, item.UID)) { item.UID = 0; } p += 8;
- if (!OctalToNumber32(p, 8, item.GID)) { item.GID = 0; } p += 8;
+ if (!OctalToNumber32(p, item.UID)) { item.UID = 0; } p += 8;
+ if (!OctalToNumber32(p, item.GID)) { item.GID = 0; } p += 8;
- RIF(ParseSize(p, item.PackSize));
+ RIF(ParseSize(p, item.PackSize, item.PackSize_IsBin));
item.Size = item.PackSize;
+ item.Size_IsBin = item.PackSize_IsBin;
p += 12;
- RIF(ParseInt64_MTime(p, item.MTime)); p += 12;
+ RIF(ParseInt64_MTime(p, item.MTime, item.MTime_IsBin)); p += 12;
UInt32 checkSum;
- RIF(OctalToNumber32(p, 8, checkSum));
+ RIF(OctalToNumber32(p, checkSum));
memset(p, ' ', 8); p += 8;
item.LinkFlag = *p++;
ReadString(p, NFileHeader::kNameSize, item.LinkName); p += NFileHeader::kNameSize;
- item.LinkNameCouldBeReduced =
+
+ /*
+ item.LinkName_CouldBeReduced =
(item.LinkName.Len() == NFileHeader::kNameSize ||
item.LinkName.Len() == NFileHeader::kNameSize - 1);
+ */
memcpy(item.Magic, p, 8); p += 8;
ReadString(p, NFileHeader::kUserNameSize, item.User); p += NFileHeader::kUserNameSize;
ReadString(p, NFileHeader::kGroupNameSize, item.Group); p += NFileHeader::kGroupNameSize;
- item.DeviceMajorDefined = (p[0] != 0); if (item.DeviceMajorDefined) { RIF(OctalToNumber32(p, 8, item.DeviceMajor)); } p += 8;
- item.DeviceMinorDefined = (p[0] != 0); if (item.DeviceMinorDefined) { RIF(OctalToNumber32(p, 8, item.DeviceMinor)); } p += 8;
+ item.DeviceMajor_Defined = (p[0] != 0); if (item.DeviceMajor_Defined) { RIF(OctalToNumber32(p, item.DeviceMajor)); } p += 8;
+ item.DeviceMinor_Defined = (p[0] != 0); if (item.DeviceMinor_Defined) { RIF(OctalToNumber32(p, item.DeviceMinor)); } p += 8;
- if (p[0] != 0)
+ if (p[0] != 0
+ && item.IsMagic_ustar_5chars()
+ && (item.LinkFlag != 'L' ))
{
- AString prefix;
- ReadString(p, NFileHeader::kPrefixSize, prefix);
- if (!prefix.IsEmpty()
- && item.IsUstarMagic()
- && (item.LinkFlag != 'L' /* || prefix != "00000000000" */ ))
- item.Name = prefix + '/' + item.Name;
+ item.Prefix_WasUsed = true;
+ ReadString(p, NFileHeader::kPrefixSize, item.Name);
+ item.Name += '/';
+ unsigned i;
+ for (i = 0; i < NFileHeader::kNameSize; i++)
+ if (buf[i] == 0)
+ break;
+ item.Name.AddFrom(buf, i);
}
-
+ else
+ ReadString(buf, NFileHeader::kNameSize, item.Name);
+
p += NFileHeader::kPrefixSize;
if (item.LinkFlag == NFileHeader::NLinkFlag::kHardLink)
@@ -255,22 +310,25 @@ static HRESULT GetNextItemReal(ISequentialInStream *stream, bool &filled, CItemE
/*
TAR standard requires sum of unsigned byte values.
- But some TAR programs use sum of signed byte values.
+ But some old TAR programs use sum of signed byte values.
So we check both values.
*/
- UInt32 checkSumReal = 0;
- Int32 checkSumReal_Signed = 0;
- for (unsigned i = 0; i < NFileHeader::kRecordSize; i++)
+ // for (int y = 0; y < 100; y++) // for debug
{
- char c = buf[i];
- checkSumReal_Signed += (signed char)c;
- checkSumReal += (Byte)buf[i];
- }
-
- if (checkSumReal != checkSum)
- {
- if ((UInt32)checkSumReal_Signed != checkSum)
- return S_OK;
+ UInt32 sum0 = 0;
+ {
+ for (unsigned i = 0; i < NFileHeader::kRecordSize; i++)
+ sum0 += (Byte)buf[i];
+ }
+ if (sum0 != checkSum)
+ {
+ Int32 sum = 0;
+ for (unsigned i = 0; i < NFileHeader::kRecordSize; i++)
+ sum += (signed char)buf[i];
+ if ((UInt32)sum != checkSum)
+ return S_OK;
+ item.IsSignedChecksum = true;
+ }
}
item.HeaderSize += NFileHeader::kRecordSize;
@@ -280,7 +338,7 @@ static HRESULT GetNextItemReal(ISequentialInStream *stream, bool &filled, CItemE
Byte isExtended = (Byte)buf[482];
if (isExtended != 0 && isExtended != 1)
return S_OK;
- RIF(ParseSize(buf + 483, item.Size));
+ RIF(ParseSize(buf + 483, item.Size, item.Size_IsBin));
UInt64 min = 0;
for (unsigned i = 0; i < 4; i++)
{
@@ -309,7 +367,7 @@ static HRESULT GetNextItemReal(ISequentialInStream *stream, bool &filled, CItemE
while (isExtended != 0)
{
size_t processedSize = NFileHeader::kRecordSize;
- RINOK(ReadStream(stream, buf, &processedSize));
+ RINOK(ReadStream(SeqStream, buf, &processedSize));
if (processedSize != NFileHeader::kRecordSize)
{
error = k_ErrorType_UnexpectedEnd;
@@ -317,6 +375,12 @@ static HRESULT GetNextItemReal(ISequentialInStream *stream, bool &filled, CItemE
}
item.HeaderSize += NFileHeader::kRecordSize;
+
+ if (OpenCallback)
+ {
+ RINOK(Progress(item, 0));
+ }
+
isExtended = (Byte)buf[21 * 24];
if (isExtended != 0 && isExtended != 1)
return S_OK;
@@ -346,172 +410,711 @@ static HRESULT GetNextItemReal(ISequentialInStream *stream, bool &filled, CItemE
return S_OK;
}
+ if (item.PackSize >= (UInt64)1 << 63)
+ return S_OK;
+
filled = true;
error = k_ErrorType_OK;
return S_OK;
}
-static HRESULT ReadDataToString(ISequentialInStream *stream, CItemEx &item, AString &s, EErrorType &error)
+HRESULT CArchive::Progress(const CItemEx &item, UInt64 posOffset)
{
- const unsigned packSize = (unsigned)item.GetPackSizeAligned();
- size_t processedSize = packSize;
- HRESULT res = ReadStream(stream, s.GetBuf(packSize), &processedSize);
- item.HeaderSize += (unsigned)processedSize;
- s.ReleaseBuf_CalcLen((unsigned)item.PackSize);
- RINOK(res);
- if (processedSize != packSize)
- error = k_ErrorType_UnexpectedEnd;
+ const UInt64 pos = item.Get_DataPos() + posOffset;
+ if (NumFiles - NumFiles_Prev < (1 << 16)
+ // && NumRecords - NumRecords_Prev < (1 << 16)
+ && pos - Pos_Prev < ((UInt32)1 << 28))
+ return S_OK;
+ {
+ Pos_Prev = pos;
+ NumFiles_Prev = NumFiles;
+ // NumRecords_Prev = NumRecords;
+ // Sleep(100); // for debug
+ return OpenCallback->SetCompleted(&NumFiles, &pos);
+ }
+}
+
+
+HRESULT CArchive::ReadDataToBuffer(const CItemEx &item,
+ CTempBuffer &tb, size_t stringLimit)
+{
+ tb.Init();
+ UInt64 packSize = item.Get_PackSize_Aligned();
+ if (packSize == 0)
+ return S_OK;
+
+ UInt64 pos;
+
+ {
+ size_t size = stringLimit;
+ if (size > packSize)
+ size = (size_t)packSize;
+ tb.Buffer.AllocAtLeast(size);
+ size_t processedSize = size;
+ const HRESULT res = ReadStream(SeqStream, tb.Buffer, &processedSize);
+ pos = processedSize;
+ if (processedSize != size)
+ {
+ error = k_ErrorType_UnexpectedEnd;
+ return res;
+ }
+ RINOK(res);
+
+ packSize -= size;
+
+ size_t i;
+ const Byte *p = tb.Buffer;
+ for (i = 0; i < size; i++)
+ if (p[i] == 0)
+ break;
+ if (i >= item.PackSize)
+ tb.StringSize_IsConfirmed = true;
+ if (i > item.PackSize)
+ {
+ tb.StringSize = (size_t)item.PackSize;
+ tb.IsNonZeroTail = true;
+ }
+ else
+ {
+ tb.StringSize = i;
+ if (i != size)
+ {
+ tb.StringSize_IsConfirmed = true;
+ if (IsBufNonZero(p + i, size - i))
+ tb.IsNonZeroTail = true;
+ }
+ }
+
+ if (packSize == 0)
+ return S_OK;
+ }
+
+ if (InStream)
+ {
+ RINOK(InStream->Seek((Int64)packSize, STREAM_SEEK_CUR, NULL));
+ return S_OK;
+ }
+ const unsigned kBufSize = 1 << 15;
+ Buffer.AllocAtLeast(kBufSize);
+
+ do
+ {
+ if (OpenCallback)
+ {
+ RINOK(Progress(item, pos));
+ }
+
+ unsigned size = kBufSize;
+ if (size > packSize)
+ size = (unsigned)packSize;
+ size_t processedSize = size;
+ const HRESULT res = ReadStream(SeqStream, Buffer, &processedSize);
+ if (processedSize != size)
+ {
+ error = k_ErrorType_UnexpectedEnd;
+ return res;
+ }
+ if (!tb.IsNonZeroTail)
+ {
+ if (IsBufNonZero(Buffer, size))
+ tb.IsNonZeroTail = true;
+ }
+ packSize -= size;
+ pos += size;
+ }
+ while (packSize != 0);
return S_OK;
}
+
-static bool ParsePaxLongName(const AString &src, AString &dest)
+
+struct CPaxInfo: public CPaxTimes
{
- dest.Empty();
- for (unsigned pos = 0;;)
+ bool DoubleTagError;
+ bool TagParsingError;
+ bool UnknownLines_Overflow;
+ bool Size_Defined;
+ bool UID_Defined;
+ bool GID_Defined;
+ bool Path_Defined;
+ bool Link_Defined;
+ bool User_Defined;
+ bool Group_Defined;
+
+ UInt64 Size;
+ UInt32 UID;
+ UInt32 GID;
+
+ AString Path;
+ AString Link;
+ AString User;
+ AString Group;
+ AString UnknownLines;
+
+ bool ParseID(const AString &val, bool &defined, UInt32 &res)
{
- if (pos >= src.Len())
+ if (defined)
+ DoubleTagError = true;
+ if (val.IsEmpty())
return false;
- const char *start = src.Ptr(pos);
- const char *end;
- const UInt32 lineLen = ConvertStringToUInt32(start, &end);
- if (end == start)
+ const char *end2;
+ res = ConvertStringToUInt32(val.Ptr(), &end2);
+ if (*end2 != 0)
return false;
- if (*end != ' ')
+ defined = true;
+ return true;
+ }
+
+ bool ParsePax(const CTempBuffer &tb, bool isFile);
+};
+
+
+static bool ParsePaxTime(const AString &src, CPaxTime &pt, bool &doubleTagError)
+{
+ if (pt.IsDefined())
+ doubleTagError = true;
+ pt.Clear();
+ const char *s = src.Ptr();
+ bool isNegative = false;
+ if (*s == '-')
+ {
+ isNegative = true;
+ s++;
+ }
+ const char *end;
+ {
+ UInt64 sec = ConvertStringToUInt64(s, &end);
+ if (s == end)
return false;
- if (lineLen > src.Len() - pos)
+ if (sec >= ((UInt64)1 << 63))
return false;
- unsigned offset = (unsigned)(end - start) + 1;
- if (lineLen < offset)
+ if (isNegative)
+ sec = -(Int64)sec;
+ pt.Sec = sec;
+ }
+ if (*end == 0)
+ {
+ pt.Ns = 0;
+ pt.NumDigits = 0;
+ return true;
+ }
+ if (*end != '.')
+ return false;
+ s = end + 1;
+
+ UInt32 ns = 0;
+ unsigned i;
+ const unsigned kNsDigits = 9;
+ for (i = 0;; i++)
+ {
+ const char c = s[i];
+ if (c == 0)
+ break;
+ if (c < '0' || c > '9')
return false;
- if (IsString1PrefixedByString2(src.Ptr(pos + offset), "path="))
+ // we ignore digits after 9 digits as GNU TAR
+ if (i < kNsDigits)
+ {
+ ns *= 10;
+ ns += c - '0';
+ }
+ }
+ pt.NumDigits = (i < kNsDigits ? i : kNsDigits);
+ while (i < kNsDigits)
+ {
+ ns *= 10;
+ i++;
+ }
+ if (isNegative && ns != 0)
+ {
+ pt.Sec--;
+ ns = (UInt32)1000 * 1000 * 1000 - ns;
+ }
+ pt.Ns = ns;
+ return true;
+}
+
+
+bool CPaxInfo::ParsePax(const CTempBuffer &tb, bool isFile)
+{
+ DoubleTagError = false;
+ TagParsingError = false;
+ UnknownLines_Overflow = false;
+ Size_Defined = false;
+ UID_Defined = false;
+ GID_Defined = false;
+ Path_Defined = false;
+ Link_Defined = false;
+ User_Defined = false;
+ Group_Defined = false;
+
+ // CPaxTimes::Clear();
+
+ const char *s = (const char *)(const void *)(const Byte *)tb.Buffer;
+ size_t rem = tb.StringSize;
+
+ Clear();
+
+ AString name, val;
+
+ while (rem != 0)
+ {
+ unsigned i;
+ for (i = 0;; i++)
{
- offset += 5; // "path="
- dest = src.Mid(pos + offset, lineLen - offset);
- if (dest.IsEmpty())
+ if (i > 24 || i >= rem) // we use limitation for size of (size) field
return false;
- if (dest.Back() != '\n')
+ if (s[i] == ' ')
+ break;
+ }
+ if (i == 0)
+ return false;
+ const char *end;
+ const UInt32 size = ConvertStringToUInt32(s, &end);
+ const unsigned offset = (unsigned)(end - s) + 1;
+ if (size > rem
+ || size <= offset + 1
+ || offset != i + 1
+ || s[size - 1] != '\n')
+ return false;
+
+ for (i = offset; i < size; i++)
+ if (s[i] == 0)
return false;
- dest.DeleteBack();
- return true;
+
+ for (i = offset; i < size - 1; i++)
+ if (s[i] == '=')
+ break;
+ if (i == size - 1)
+ return false;
+
+ name.SetFrom(s + offset, i - offset);
+ val.SetFrom(s + i + 1, size - 1 - (i + 1));
+
+ bool parsed = false;
+ if (isFile)
+ {
+ bool isDetectedName = true;
+ // only lower case (name) is supported
+ if (name.IsEqualTo("path"))
+ {
+ if (Path_Defined)
+ DoubleTagError = true;
+ Path = val;
+ Path_Defined = true;
+ parsed = true;
+ }
+ else if (name.IsEqualTo("linkpath"))
+ {
+ if (Link_Defined)
+ DoubleTagError = true;
+ Link = val;
+ Link_Defined = true;
+ parsed = true;
+ }
+ else if (name.IsEqualTo("uname"))
+ {
+ if (User_Defined)
+ DoubleTagError = true;
+ User = val;
+ User_Defined = true;
+ parsed = true;
+ }
+ else if (name.IsEqualTo("gname"))
+ {
+ if (Group_Defined)
+ DoubleTagError = true;
+ Group = val;
+ Group_Defined = true;
+ parsed = true;
+ }
+ else if (name.IsEqualTo("uid"))
+ {
+ parsed = ParseID(val, UID_Defined, UID);
+ }
+ else if (name.IsEqualTo("gid"))
+ {
+ parsed = ParseID(val, GID_Defined, GID);
+ }
+ else if (name.IsEqualTo("size"))
+ {
+ if (Size_Defined)
+ DoubleTagError = true;
+ Size_Defined = false;
+ if (!val.IsEmpty())
+ {
+ const char *end2;
+ Size = ConvertStringToUInt64(val.Ptr(), &end2);
+ if (*end2 == 0)
+ {
+ Size_Defined = true;
+ parsed = true;
+ }
+ }
+ }
+ else if (name.IsEqualTo("mtime"))
+ { parsed = ParsePaxTime(val, MTime, DoubleTagError); }
+ else if (name.IsEqualTo("atime"))
+ { parsed = ParsePaxTime(val, ATime, DoubleTagError); }
+ else if (name.IsEqualTo("ctime"))
+ { parsed = ParsePaxTime(val, CTime, DoubleTagError); }
+ else
+ isDetectedName = false;
+ if (isDetectedName && !parsed)
+ TagParsingError = true;
}
- pos += lineLen;
+ if (!parsed)
+ {
+ if (!UnknownLines_Overflow)
+ {
+ const unsigned addSize = size - offset;
+ if (UnknownLines.Len() + addSize < (1 << 16))
+ UnknownLines.AddFrom(s + offset, addSize);
+ else
+ UnknownLines_Overflow = true;
+ }
+ }
+
+ s += size;
+ rem -= size;
}
+ return true;
}
-HRESULT ReadItem(ISequentialInStream *stream, bool &filled, CItemEx &item, EErrorType &error)
+
+HRESULT CArchive::ReadItem2(CItemEx &item)
{
+ // CItem
+
+ item.SparseBlocks.Clear();
+ item.PaxTimes.Clear();
+
+ // CItemEx
+
item.HeaderSize = 0;
+ item.Num_Pax_Records = 0;
- bool flagL = false;
- bool flagK = false;
- AString nameL;
- AString nameK;
- AString pax;
+ item.LongName_WasUsed = false;
+ item.LongName_WasUsed_2 = false;
+
+ item.LongLink_WasUsed = false;
+ item.LongLink_WasUsed_2 = false;
+
+ item.HeaderError = false;
+ item.IsSignedChecksum = false;
+ item.Prefix_WasUsed = false;
- for (;;)
+ item.Pax_Error = false;
+ item.Pax_Overflow = false;
+ item.pax_path_WasUsed = false;
+ item.pax_link_WasUsed = false;
+ item.pax_size_WasUsed = false;
+
+ item.PaxExtra.Clear();
+
+ item.EncodingCharacts.Clear();
+
+ // CArchive temp variable
+
+ NameBuf.Init();
+ LinkBuf.Init();
+ PaxBuf.Init();
+ PaxBuf_global.Init();
+
+ for (unsigned recordIndex = 0;; recordIndex++)
{
- RINOK(GetNextItemReal(stream, filled, item, error));
+ if (OpenCallback)
+ {
+ RINOK(Progress(item, 0));
+ }
+
+ RINOK(GetNextItemReal(item));
+
+ // NumRecords++;
+
if (!filled)
{
- if (error == k_ErrorType_OK && (flagL || flagK))
+ if (error == k_ErrorType_OK)
+ if (item.LongName_WasUsed ||
+ item.LongLink_WasUsed ||
+ item.Num_Pax_Records != 0)
error = k_ErrorType_Corrupted;
- return S_OK;
}
if (error != k_ErrorType_OK)
return S_OK;
- if (item.LinkFlag == NFileHeader::NLinkFlag::kGnu_LongName || // file contains a long name
- item.LinkFlag == NFileHeader::NLinkFlag::kGnu_LongLink) // file contains a long linkname
+ const char lf = item.LinkFlag;
+ if (lf == NFileHeader::NLinkFlag::kGnu_LongName ||
+ lf == NFileHeader::NLinkFlag::kGnu_LongLink)
{
- AString *name;
- if (item.LinkFlag == NFileHeader::NLinkFlag::kGnu_LongName)
- { if (flagL) return S_OK; flagL = true; name = &nameL; }
- else
- { if (flagK) return S_OK; flagK = true; name = &nameK; }
-
+ // GNU tar ignores item.Name after LinkFlag test
+ // 22.00 : now we also ignore item.Name here
+ /*
if (item.Name != NFileHeader::kLongLink &&
item.Name != NFileHeader::kLongLink2)
+ {
+ break;
+ // return S_OK;
+ }
+ */
+
+ CTempBuffer *tb =
+ lf == NFileHeader::NLinkFlag::kGnu_LongName ?
+ &NameBuf :
+ &LinkBuf;
+
+ /*
+ if (item.PackSize > (1 << 29))
+ {
+ // break;
return S_OK;
- if (item.PackSize > (1 << 14))
- return S_OK;
+ }
+ */
- RINOK(ReadDataToString(stream, item, *name, error));
+ const unsigned kLongNameSizeMax = (unsigned)1 << 14;
+ RINOK(ReadDataToBuffer(item, *tb, kLongNameSizeMax));
if (error != k_ErrorType_OK)
return S_OK;
+ if (lf == NFileHeader::NLinkFlag::kGnu_LongName)
+ {
+ item.LongName_WasUsed_2 =
+ item.LongName_WasUsed;
+ item.LongName_WasUsed = true;
+ }
+ else
+ {
+ item.LongLink_WasUsed_2 =
+ item.LongLink_WasUsed;
+ item.LongLink_WasUsed = true;
+ }
+
+ if (!tb->StringSize_IsConfirmed)
+ tb->StringSize = 0;
+ item.HeaderSize += item.Get_PackSize_Aligned();
+ if (tb->StringSize == 0 ||
+ tb->StringSize + 1 != item.PackSize)
+ item.HeaderError = true;
+ if (tb->IsNonZeroTail)
+ item.HeaderError = true;
continue;
}
- switch (item.LinkFlag)
+ if (lf == NFileHeader::NLinkFlag::kGlobal ||
+ lf == NFileHeader::NLinkFlag::kPax ||
+ lf == NFileHeader::NLinkFlag::kPax_2)
{
- case 'g':
- case 'x':
- case 'X':
+ // GNU tar ignores item.Name after LinkFlag test
+ // 22.00 : now we also ignore item.Name here
+ /*
+ if (item.PackSize > (UInt32)1 << 26)
{
- const char *s = item.Name.Ptr();
- if (IsString1PrefixedByString2(s, "./"))
- s += 2;
- if (IsString1PrefixedByString2(s, "./"))
- s += 2;
- if ( IsString1PrefixedByString2(s, "PaxHeader/")
- || IsString1PrefixedByString2(s, "PaxHeaders.X/")
- || IsString1PrefixedByString2(s, "PaxHeaders.4467/")
- || StringsAreEqual_Ascii(s, "@PaxHeader")
- )
- {
- RINOK(ReadDataToString(stream, item, pax, error));
- if (error != k_ErrorType_OK)
- return S_OK;
- continue;
- }
- break;
+ break; // we don't want big PaxBuf files
+ // return S_OK;
}
- case NFileHeader::NLinkFlag::kDumpDir:
+ */
+ const unsigned kParsingPaxSizeMax = (unsigned)1 << 26;
+
+ const bool isStartHeader = (item.HeaderSize == NFileHeader::kRecordSize);
+
+ CTempBuffer *tb = (lf == NFileHeader::NLinkFlag::kGlobal ? &PaxBuf_global : &PaxBuf);
+
+ RINOK(ReadDataToBuffer(item, *tb, kParsingPaxSizeMax));
+ if (error != k_ErrorType_OK)
+ return S_OK;
+
+ item.HeaderSize += item.Get_PackSize_Aligned();
+
+ if (tb->StringSize != item.PackSize
+ || tb->StringSize == 0
+ || tb->IsNonZeroTail)
+ item.Pax_Error = true;
+
+ item.Num_Pax_Records++;
+ if (lf != NFileHeader::NLinkFlag::kGlobal)
{
- break;
- // GNU Extensions to the Archive Format
+ item.PaxExtra.RecordPath = item.Name;
+ continue;
}
- case NFileHeader::NLinkFlag::kSparse:
+ // break; // for debug
{
- break;
- // GNU Extensions to the Archive Format
+ if (PaxGlobal_Defined)
+ _is_PaxGlobal_Error = true;
+ CPaxInfo paxInfo;
+ if (paxInfo.ParsePax(PaxBuf_global, false))
+ {
+ PaxGlobal.RawLines = paxInfo.UnknownLines;
+ PaxGlobal.RecordPath = item.Name;
+ PaxGlobal_Defined = true;
+ }
+ else
+ _is_PaxGlobal_Error = true;
+ if (isStartHeader)
+ {
+ // we skip global pax header info after parsing
+ item.HeaderPos += item.HeaderSize;
+ item.HeaderSize = 0;
+ }
}
- default:
- if (item.LinkFlag > '7' || (item.LinkFlag < '0' && item.LinkFlag != 0))
- return S_OK;
+ continue;
}
- if (flagL)
+ /*
+ if (lf == NFileHeader::NLinkFlag::kDumpDir ||
+ lf == NFileHeader::NLinkFlag::kSparse)
{
- item.Name = nameL;
- item.NameCouldBeReduced = false;
+ // GNU Extensions to the Archive Format
+ break;
}
-
- if (flagK)
+ if (lf > '7' || (lf < '0' && lf != 0))
{
- item.LinkName = nameK;
- item.LinkNameCouldBeReduced = false;
+ break;
+ // return S_OK;
}
-
- error = k_ErrorType_OK;
-
- if (!pax.IsEmpty())
+ */
+ break;
+ }
+
+ // we still use name from main header, if long_name is bad
+ if (item.LongName_WasUsed && NameBuf.StringSize != 0)
+ {
+ NameBuf.CopyToString(item.Name);
+ // item.Name_CouldBeReduced = false;
+ }
+
+ if (item.LongLink_WasUsed)
+ {
+ // we use empty link, if long_link is bad
+ LinkBuf.CopyToString(item.LinkName);
+ // item.LinkName_CouldBeReduced = false;
+ }
+
+ error = k_ErrorType_OK;
+
+ if (PaxBuf.StringSize != 0)
+ {
+ CPaxInfo paxInfo;
+ if (!paxInfo.ParsePax(PaxBuf, true))
+ item.Pax_Error = true;
+ else
{
- AString name;
- if (ParsePaxLongName(pax, name))
- item.Name = name;
- else
+ if (paxInfo.Path_Defined) // if (!paxInfo.Path.IsEmpty())
+ {
+ item.Name = paxInfo.Path;
+ item.pax_path_WasUsed = true;
+ }
+ if (paxInfo.Link_Defined) // (!paxInfo.Link.IsEmpty())
+ {
+ item.LinkName = paxInfo.Link;
+ item.pax_link_WasUsed = true;
+ }
+ if (paxInfo.User_Defined)
+ {
+ item.User = paxInfo.User;
+ // item.pax_uname_WasUsed = true;
+ }
+ if (paxInfo.Group_Defined)
+ {
+ item.Group = paxInfo.Group;
+ // item.pax_gname_WasUsed = true;
+ }
+ if (paxInfo.UID_Defined)
{
- // no "path" property is allowed in pax4467
- // error = k_ErrorType_Warning;
+ item.UID = (UInt32)paxInfo.UID;
}
- pax.Empty();
+ if (paxInfo.GID_Defined)
+ {
+ item.GID = (UInt32)paxInfo.GID;
+ }
+
+ if (paxInfo.Size_Defined)
+ {
+ const UInt64 piSize = paxInfo.Size;
+ // GNU TAR ignores (item.Size) in that case
+ if (item.Size != 0 && item.Size != piSize)
+ item.Pax_Error = true;
+ item.Size = piSize;
+ item.PackSize = piSize;
+ item.pax_size_WasUsed = true;
+ }
+
+ item.PaxTimes = paxInfo;
+ item.PaxExtra.RawLines = paxInfo.UnknownLines;
+ if (paxInfo.UnknownLines_Overflow)
+ item.Pax_Overflow = true;
+ if (paxInfo.TagParsingError)
+ item.Pax_Error = true;
+ if (paxInfo.DoubleTagError)
+ item.Pax_Error = true;
}
+ }
- return S_OK;
+ return S_OK;
+}
+
+
+
+HRESULT CArchive::ReadItem(CItemEx &item)
+{
+ item.HeaderPos = _phySize;
+
+ const HRESULT res = ReadItem2(item);
+
+ /*
+ if (error == k_ErrorType_Warning)
+ _is_Warning = true;
+ else
+ */
+
+ if (error != k_ErrorType_OK)
+ _error = error;
+
+ RINOK(res);
+
+ if (filled)
+ {
+ if (item.IsMagic_GNU())
+ _are_Gnu = true;
+ else if (item.IsMagic_Posix_ustar_00())
+ _are_Posix = true;
+
+ if (item.Num_Pax_Records != 0)
+ _are_Pax = true;
+
+ if (item.PaxTimes.MTime.IsDefined()) _are_mtime = true;
+ if (item.PaxTimes.ATime.IsDefined()) _are_atime = true;
+ if (item.PaxTimes.CTime.IsDefined()) _are_ctime = true;
+
+ if (item.pax_path_WasUsed)
+ _are_pax_path = true;
+ if (item.pax_link_WasUsed)
+ _are_pax_link = true;
+ if (item.LongName_WasUsed)
+ _are_LongName = true;
+ if (item.LongLink_WasUsed)
+ _are_LongLink = true;
+ if (item.Prefix_WasUsed)
+ _pathPrefix_WasUsed = true;
+ /*
+ if (item.IsSparse())
+ _isSparse = true;
+ */
+ if (item.Is_PaxExtendedHeader())
+ _are_Pax_Items = true;
+ if (item.IsThereWarning()
+ || item.HeaderError
+ || item.Pax_Error)
+ _is_Warning = true;
}
+
+ const UInt64 headerEnd = item.HeaderPos + item.HeaderSize;
+ // _headersSize += headerEnd - _phySize;
+ // we don't count skipped records
+ _headersSize += item.HeaderSize;
+ _phySize = headerEnd;
+ return S_OK;
}
}}
diff --git a/CPP/7zip/Archive/Tar/TarIn.h b/CPP/7zip/Archive/Tar/TarIn.h
index 1c508bcc..e99599a4 100644..100755
--- a/CPP/7zip/Archive/Tar/TarIn.h
+++ b/CPP/7zip/Archive/Tar/TarIn.h
@@ -3,7 +3,7 @@
#ifndef __ARCHIVE_TAR_IN_H
#define __ARCHIVE_TAR_IN_H
-#include "../../IStream.h"
+#include "../IArchive.h"
#include "TarItem.h"
@@ -14,11 +14,133 @@ enum EErrorType
{
k_ErrorType_OK,
k_ErrorType_Corrupted,
- k_ErrorType_UnexpectedEnd,
- k_ErrorType_Warning
+ k_ErrorType_UnexpectedEnd
+ // , k_ErrorType_Warning
+};
+
+
+struct CTempBuffer
+{
+ CByteBuffer Buffer;
+ size_t StringSize; // num characters before zero Byte (StringSize <= item.PackSize)
+ bool IsNonZeroTail;
+ bool StringSize_IsConfirmed;
+
+ void CopyToString(AString &s)
+ {
+ s.Empty();
+ if (StringSize != 0)
+ s.SetFrom((const char *)(const void *)(const Byte *)Buffer, (unsigned)StringSize);
+ }
+
+ void Init()
+ {
+ StringSize = 0;
+ IsNonZeroTail = false;
+ StringSize_IsConfirmed = false;
+ }
+};
+
+
+class CArchive
+{
+public:
+ bool _phySize_Defined;
+ bool _is_Warning;
+ bool PaxGlobal_Defined;
+ bool _is_PaxGlobal_Error;
+ bool _are_Pax_Items;
+ bool _are_Gnu;
+ bool _are_Posix;
+ bool _are_Pax;
+ bool _are_mtime;
+ bool _are_atime;
+ bool _are_ctime;
+ bool _are_pax_path;
+ bool _are_pax_link;
+ bool _are_LongName;
+ bool _are_LongLink;
+ bool _pathPrefix_WasUsed;
+ // bool _isSparse;
+
+ // temp internal vars for ReadItem():
+ bool filled;
+private:
+ EErrorType error;
+
+public:
+ UInt64 _phySize;
+ UInt64 _headersSize;
+ EErrorType _error;
+
+ ISequentialInStream *SeqStream;
+ IInStream *InStream;
+ IArchiveOpenCallback *OpenCallback;
+ UInt64 NumFiles;
+ UInt64 NumFiles_Prev;
+ UInt64 Pos_Prev;
+ // UInt64 NumRecords;
+ // UInt64 NumRecords_Prev;
+
+ CPaxExtra PaxGlobal;
+
+ void Clear()
+ {
+ SeqStream = NULL;
+ InStream = NULL;
+ OpenCallback = NULL;
+ NumFiles = 0;
+ NumFiles_Prev = 0;
+ Pos_Prev = 0;
+ // NumRecords = 0;
+ // NumRecords_Prev = 0;
+
+ PaxGlobal.Clear();
+ PaxGlobal_Defined = false;
+ _is_PaxGlobal_Error = false;
+ _are_Pax_Items = false; // if there are final paxItems
+ _are_Gnu = false;
+ _are_Posix = false;
+ _are_Pax = false;
+ _are_mtime = false;
+ _are_atime = false;
+ _are_ctime = false;
+ _are_pax_path = false;
+ _are_pax_link = false;
+ _are_LongName = false;
+ _are_LongLink = false;
+ _pathPrefix_WasUsed = false;
+ // _isSparse = false;
+
+ _is_Warning = false;
+ _error = k_ErrorType_OK;
+
+ _phySize_Defined = false;
+ _phySize = 0;
+ _headersSize = 0;
+ }
+
+private:
+ CTempBuffer NameBuf;
+ CTempBuffer LinkBuf;
+ CTempBuffer PaxBuf;
+ CTempBuffer PaxBuf_global;
+
+ CByteBuffer Buffer;
+
+ HRESULT ReadDataToBuffer(const CItemEx &item, CTempBuffer &tb, size_t stringLimit);
+ HRESULT Progress(const CItemEx &item, UInt64 posOffset);
+ HRESULT GetNextItemReal(CItemEx &item);
+ HRESULT ReadItem2(CItemEx &itemInfo);
+public:
+ CArchive()
+ {
+ // we will call Clear() in CHandler::Close().
+ // Clear(); // it's not required here
+ }
+ HRESULT ReadItem(CItemEx &itemInfo);
};
-HRESULT ReadItem(ISequentialInStream *stream, bool &filled, CItemEx &itemInfo, EErrorType &error);
API_FUNC_IsArc IsArc_Tar(const Byte *p, size_t size);
diff --git a/CPP/7zip/Archive/Tar/TarItem.h b/CPP/7zip/Archive/Tar/TarItem.h
index f947786f..738618f2 100644..100755
--- a/CPP/7zip/Archive/Tar/TarItem.h
+++ b/CPP/7zip/Archive/Tar/TarItem.h
@@ -6,8 +6,6 @@
#include "../../../Common/MyLinux.h"
#include "../../../Common/UTFConvert.h"
-#include "../Common/ItemNameUtils.h"
-
#include "TarHeader.h"
namespace NArchive {
@@ -19,50 +17,149 @@ struct CSparseBlock
UInt64 Size;
};
+
+enum EPaxTimeRemoveZeroMode
+{
+ k_PaxTimeMode_DontRemoveZero,
+ k_PaxTimeMode_RemoveZero_if_PureSecondOnly,
+ k_PaxTimeMode_RemoveZero_Always
+};
+
+struct CTimeOptions
+{
+ EPaxTimeRemoveZeroMode RemoveZeroMode;
+ unsigned NumDigitsMax;
+
+ void Init()
+ {
+ RemoveZeroMode = k_PaxTimeMode_RemoveZero_if_PureSecondOnly;
+ NumDigitsMax = 0;
+ }
+ CTimeOptions() { Init(); }
+};
+
+
+struct CPaxTime
+{
+ Int32 NumDigits; // -1 means undefined
+ UInt32 Ns; // it's smaller than 1G. Even if (Sec < 0), larger (Ns) value means newer files.
+ Int64 Sec; // can be negative
+
+ Int64 GetSec() const { return NumDigits != -1 ? Sec : 0; }
+
+ bool IsDefined() const { return NumDigits != -1; }
+ // bool IsDefined_And_nonZero() const { return NumDigits != -1 && (Sec != 0 || Ns != 0); }
+
+ void Clear()
+ {
+ NumDigits = -1;
+ Ns = 0;
+ Sec = 0;
+ }
+ CPaxTime() { Clear(); }
+
+ /*
+ void ReducePrecison(int numDigits)
+ {
+ // we don't use this->NumDigits here
+ if (numDigits > 0)
+ {
+ if (numDigits >= 9)
+ return;
+ UInt32 r = 1;
+ for (unsigned i = numDigits; i < 9; i++)
+ r *= 10;
+ Ns /= r;
+ Ns *= r;
+ return;
+ }
+ Ns = 0;
+ if (numDigits == 0)
+ return;
+ UInt32 r;
+ if (numDigits == -1) r = 60;
+ else if (numDigits == -2) r = 60 * 60;
+ else if (numDigits == -3) r = 60 * 60 * 24;
+ else return;
+ Sec /= r;
+ Sec *= r;
+ }
+ */
+};
+
+
+struct CPaxTimes
+{
+ CPaxTime MTime;
+ CPaxTime ATime;
+ CPaxTime CTime;
+
+ void Clear()
+ {
+ MTime.Clear();
+ ATime.Clear();
+ CTime.Clear();
+ }
+
+ /*
+ void ReducePrecison(int numDigits)
+ {
+ MTime.ReducePrecison(numDigits);
+ CTime.ReducePrecison(numDigits);
+ ATime.ReducePrecison(numDigits);
+ }
+ */
+};
+
+
struct CItem
{
- AString Name;
UInt64 PackSize;
UInt64 Size;
Int64 MTime;
+ char LinkFlag;
+ bool DeviceMajor_Defined;
+ bool DeviceMinor_Defined;
+
UInt32 Mode;
UInt32 UID;
UInt32 GID;
UInt32 DeviceMajor;
UInt32 DeviceMinor;
+ AString Name;
AString LinkName;
AString User;
AString Group;
char Magic[8];
- char LinkFlag;
- bool DeviceMajorDefined;
- bool DeviceMinorDefined;
+
+ CPaxTimes PaxTimes;
CRecordVector<CSparseBlock> SparseBlocks;
- void SetDefaultWriteFields()
+ void SetMagic_Posix(bool posixMode)
{
- DeviceMajorDefined = false;
- DeviceMinorDefined = false;
- UID = 0;
- GID = 0;
- memcpy(Magic, NFileHeader::NMagic::kUsTar_GNU, 8);
+ memcpy(Magic, posixMode ?
+ NFileHeader::NMagic::k_Posix_ustar_00 :
+ NFileHeader::NMagic::k_GNU_ustar__,
+ 8);
}
- bool IsSymLink() const { return LinkFlag == NFileHeader::NLinkFlag::kSymLink && (Size == 0); }
- bool IsHardLink() const { return LinkFlag == NFileHeader::NLinkFlag::kHardLink; }
- bool IsSparse() const { return LinkFlag == NFileHeader::NLinkFlag::kSparse; }
- UInt64 GetUnpackSize() const { return IsSymLink() ? LinkName.Len() : Size; }
- bool IsPaxExtendedHeader() const
+ bool Is_SymLink() const { return LinkFlag == NFileHeader::NLinkFlag::kSymLink && (Size == 0); }
+ bool Is_HardLink() const { return LinkFlag == NFileHeader::NLinkFlag::kHardLink; }
+ bool Is_Sparse() const { return LinkFlag == NFileHeader::NLinkFlag::kSparse; }
+
+ UInt64 Get_UnpackSize() const { return Is_SymLink() ? LinkName.Len() : Size; }
+
+ bool Is_PaxExtendedHeader() const
{
switch (LinkFlag)
{
- case 'g':
- case 'x':
- case 'X': // Check it
+ case NFileHeader::NLinkFlag::kPax:
+ case NFileHeader::NLinkFlag::kPax_2:
+ case NFileHeader::NLinkFlag::kGlobal:
return true;
}
return false;
@@ -72,6 +169,17 @@ struct CItem
{
return (Mode & ~(UInt32)MY_LIN_S_IFMT) | Get_FileTypeMode_from_LinkFlag();
}
+
+ void Set_LinkFlag_for_File(UInt32 mode)
+ {
+ Byte lf = NFileHeader::NLinkFlag::kNormal;
+ if (MY_LIN_S_ISCHR(mode)) lf = NFileHeader::NLinkFlag::kCharacter;
+ else if (MY_LIN_S_ISBLK(mode)) lf = NFileHeader::NLinkFlag::kBlock;
+ else if (MY_LIN_S_ISFIFO(mode)) lf = NFileHeader::NLinkFlag::kFIFO;
+ // else if (MY_LIN_S_ISDIR(mode)) lf = NFileHeader::NLinkFlag::kDirectory;
+ // else if (MY_LIN_S_ISLNK(mode)) lf = NFileHeader::NLinkFlag::kSymLink;
+ LinkFlag = lf;
+ }
UInt32 Get_FileTypeMode_from_LinkFlag() const
{
@@ -82,10 +190,10 @@ struct CItem
case NFileHeader::NLinkFlag::kDumpDir:
return MY_LIN_S_IFDIR;
*/
- case NFileHeader::NLinkFlag::kSymLink: return MY_LIN_S_IFLNK;
- case NFileHeader::NLinkFlag::kBlock: return MY_LIN_S_IFBLK;
- case NFileHeader::NLinkFlag::kCharacter: return MY_LIN_S_IFCHR;
- case NFileHeader::NLinkFlag::kFIFO: return MY_LIN_S_IFIFO;
+ case NFileHeader::NLinkFlag::kSymLink: return MY_LIN_S_IFLNK;
+ case NFileHeader::NLinkFlag::kBlock: return MY_LIN_S_IFBLK;
+ case NFileHeader::NLinkFlag::kCharacter: return MY_LIN_S_IFCHR;
+ case NFileHeader::NLinkFlag::kFIFO: return MY_LIN_S_IFIFO;
// case return MY_LIN_S_IFSOCK;
}
@@ -104,20 +212,41 @@ struct CItem
case NFileHeader::NLinkFlag::kOldNormal:
case NFileHeader::NLinkFlag::kNormal:
case NFileHeader::NLinkFlag::kSymLink:
- return NItemName::HasTailSlash(Name, CP_OEMCP);
+ if (Name.IsEmpty())
+ return false;
+ // GNU TAR uses last character as directory marker
+ // we also do it
+ return Name.Back() == '/';
+ // return NItemName::HasTailSlash(Name, CP_OEMCP);
}
return false;
}
- bool IsUstarMagic() const
+ bool IsMagic_ustar_5chars() const
+ {
+ for (unsigned i = 0; i < 5; i++)
+ if (Magic[i] != NFileHeader::NMagic::k_GNU_ustar__[i])
+ return false;
+ return true;
+ }
+
+ bool IsMagic_Posix_ustar_00() const
+ {
+ for (unsigned i = 0; i < 8; i++)
+ if (Magic[i] != NFileHeader::NMagic::k_Posix_ustar_00[i])
+ return false;
+ return true;
+ }
+
+ bool IsMagic_GNU() const
{
- for (int i = 0; i < 5; i++)
- if (Magic[i] != NFileHeader::NMagic::kUsTar_GNU[i])
+ for (unsigned i = 0; i < 8; i++)
+ if (Magic[i] != NFileHeader::NMagic::k_GNU_ustar__[i])
return false;
return true;
}
- UInt64 GetPackSizeAligned() const { return (PackSize + 0x1FF) & (~((UInt64)0x1FF)); }
+ UInt64 Get_PackSize_Aligned() const { return (PackSize + 0x1FF) & (~((UInt64)0x1FF)); }
bool IsThereWarning() const
{
@@ -163,18 +292,67 @@ struct CEncodingCharacts
};
+struct CPaxExtra
+{
+ AString RecordPath;
+ AString RawLines;
+
+ void Clear()
+ {
+ RecordPath.Empty();
+ RawLines.Empty();
+ }
+
+ void Print_To_String(AString &s) const
+ {
+ if (!RecordPath.IsEmpty())
+ {
+ s += RecordPath;
+ s.Add_LF();
+ }
+ if (!RawLines.IsEmpty())
+ s += RawLines;
+ }
+};
+
struct CItemEx: public CItem
{
+ bool HeaderError;
+
+ bool IsSignedChecksum;
+ bool Prefix_WasUsed;
+
+ bool Pax_Error;
+ bool Pax_Overflow;
+ bool pax_path_WasUsed;
+ bool pax_link_WasUsed;
+ bool pax_size_WasUsed;
+
+ bool MTime_IsBin;
+ bool PackSize_IsBin;
+ bool Size_IsBin;
+
+ bool LongName_WasUsed;
+ bool LongName_WasUsed_2;
+
+ bool LongLink_WasUsed;
+ bool LongLink_WasUsed_2;
+
+ // bool Name_CouldBeReduced;
+ // bool LinkName_CouldBeReduced;
+
UInt64 HeaderPos;
- unsigned HeaderSize;
- bool NameCouldBeReduced;
- bool LinkNameCouldBeReduced;
+ UInt64 HeaderSize;
+
+ UInt64 Num_Pax_Records;
+ CPaxExtra PaxExtra;
CEncodingCharacts EncodingCharacts;
- UInt64 GetDataPosition() const { return HeaderPos + HeaderSize; }
- UInt64 GetFullSize() const { return HeaderSize + PackSize; }
+ UInt64 Get_DataPos() const { return HeaderPos + HeaderSize; }
+ // UInt64 GetFullSize() const { return HeaderSize + PackSize; }
+ UInt64 Get_FullSize_Aligned() const { return HeaderSize + Get_PackSize_Aligned(); }
};
}}
diff --git a/CPP/7zip/Archive/Tar/TarOut.cpp b/CPP/7zip/Archive/Tar/TarOut.cpp
index 271b854a..f73c625b 100644..100755
--- a/CPP/7zip/Archive/Tar/TarOut.cpp
+++ b/CPP/7zip/Archive/Tar/TarOut.cpp
@@ -2,6 +2,10 @@
#include "StdAfx.h"
+#include "../../../../C/7zCrc.h"
+
+#include "../../../Common/IntToString.h"
+
#include "../../Common/StreamUtils.h"
#include "TarOut.h"
@@ -9,23 +13,27 @@
namespace NArchive {
namespace NTar {
-HRESULT COutArchive::WriteBytes(const void *data, unsigned size)
-{
- Pos += size;
- return WriteStream(m_Stream, data, size);
-}
+using namespace NFileHeader;
+
+// it's path prefix assigned by 7-Zip to show that file path was cut
+#define K_PREFIX_PATH_CUT "@PathCut"
+
+static const UInt32 k_7_oct_digits_Val_Max = ((UInt32)1 << (7 * 3)) - 1;
-static bool WriteOctal_8(char *s, UInt32 val)
+static void WriteOctal_8(char *s, UInt32 val)
{
const unsigned kNumDigits = 8 - 1;
if (val >= ((UInt32)1 << (kNumDigits * 3)))
- return false;
+ {
+ val = 0;
+ // return false;
+ }
for (unsigned i = 0; i < kNumDigits; i++)
{
s[kNumDigits - 1 - i] = (char)('0' + (val & 7));
val >>= 3;
}
- return true;
+ // return true;
}
static void WriteBin_64bit(char *s, UInt64 val)
@@ -68,61 +76,93 @@ static void CopyString(char *dest, const AString &src, unsigned maxSize)
unsigned len = src.Len();
if (len == 0)
return;
- // 21.07: we don't require additional 0 character at the end
+ // 21.07: new gnu : we don't require additional 0 character at the end
+ // if (len >= maxSize)
if (len > maxSize)
{
len = maxSize;
- // return false;
+ /*
+ // oldgnu needs 0 character at the end
+ len = maxSize - 1;
+ dest[len] = 0;
+ */
}
memcpy(dest, src.Ptr(), len);
- // return true;
}
-#define RETURN_IF_NOT_TRUE(x) { if (!(x)) return E_FAIL; }
+// #define RETURN_IF_NOT_TRUE(x) { if (!(x)) return E_INVALIDARG; }
+#define RETURN_IF_NOT_TRUE(x) { x; }
#define COPY_STRING_CHECK(dest, src, size) \
CopyString(dest, src, size); dest += (size);
#define WRITE_OCTAL_8_CHECK(dest, src) \
- RETURN_IF_NOT_TRUE(WriteOctal_8(dest, src));
+ RETURN_IF_NOT_TRUE(WriteOctal_8(dest, src))
-HRESULT COutArchive::WriteHeaderReal(const CItem &item)
+HRESULT COutArchive::WriteHeaderReal(const CItem &item, bool isPax
+ // , bool zero_PackSize
+ // , bool zero_MTime
+ )
{
- char record[NFileHeader::kRecordSize];
- memset(record, 0, NFileHeader::kRecordSize);
+ /*
+ if (isPax) { we don't use Glob_Name and Prefix }
+ if (!isPax)
+ {
+ we use Glob_Name if it's not empty
+ we use Prefix if it's not empty
+ }
+ */
+ char record[kRecordSize];
+ memset(record, 0, kRecordSize);
char *cur = record;
- COPY_STRING_CHECK (cur, item.Name, NFileHeader::kNameSize);
+ COPY_STRING_CHECK (cur,
+ (!isPax && !Glob_Name.IsEmpty()) ? Glob_Name : item.Name,
+ kNameSize);
- WRITE_OCTAL_8_CHECK (cur, item.Mode); cur += 8;
+ WRITE_OCTAL_8_CHECK (cur, item.Mode); cur += 8; // & k_7_oct_digits_Val_Max
WRITE_OCTAL_8_CHECK (cur, item.UID); cur += 8;
WRITE_OCTAL_8_CHECK (cur, item.GID); cur += 8;
- WriteOctal_12(cur, item.PackSize); cur += 12;
- WriteOctal_12_Signed(cur, item.MTime); cur += 12;
+ WriteOctal_12 (cur, /* zero_PackSize ? 0 : */ item.PackSize); cur += 12;
+ WriteOctal_12_Signed (cur, /* zero_MTime ? 0 : */ item.MTime); cur += 12;
- memset(cur, ' ', 8); // checksum field
+ // we will use binary init for checksum instead of memset
+ // checksum field:
+ // memset(cur, ' ', 8);
cur += 8;
*cur++ = item.LinkFlag;
- COPY_STRING_CHECK (cur, item.LinkName, NFileHeader::kNameSize);
+ COPY_STRING_CHECK (cur, item.LinkName, kNameSize);
memcpy(cur, item.Magic, 8);
cur += 8;
- COPY_STRING_CHECK (cur, item.User, NFileHeader::kUserNameSize);
- COPY_STRING_CHECK (cur, item.Group, NFileHeader::kGroupNameSize);
+ COPY_STRING_CHECK (cur, item.User, kUserNameSize);
+ COPY_STRING_CHECK (cur, item.Group, kGroupNameSize);
- if (item.DeviceMajorDefined)
- WRITE_OCTAL_8_CHECK (cur, item.DeviceMajor);
+ const bool needDevice = (IsPosixMode && !isPax);
+
+ if (item.DeviceMajor_Defined)
+ WRITE_OCTAL_8_CHECK (cur, item.DeviceMajor)
+ else if (needDevice)
+ WRITE_OCTAL_8_CHECK (cur, 0)
cur += 8;
- if (item.DeviceMinorDefined)
- WRITE_OCTAL_8_CHECK (cur, item.DeviceMinor);
+
+ if (item.DeviceMinor_Defined)
+ WRITE_OCTAL_8_CHECK (cur, item.DeviceMinor)
+ else if (needDevice)
+ WRITE_OCTAL_8_CHECK (cur, 0)
cur += 8;
- if (item.IsSparse())
+ if (!isPax && !Prefix.IsEmpty())
+ {
+ COPY_STRING_CHECK (cur, Prefix, kPrefixSize);
+ }
+
+ if (item.Is_Sparse())
{
record[482] = (char)(item.SparseBlocks.Size() > 4 ? 1 : 0);
WriteOctal_12(record + 483, item.Size);
@@ -136,31 +176,31 @@ HRESULT COutArchive::WriteHeaderReal(const CItem &item)
}
{
- UInt32 checkSum = 0;
+ UInt32 sum = (unsigned)(' ') * 8; // we use binary init
{
- for (unsigned i = 0; i < NFileHeader::kRecordSize; i++)
- checkSum += (Byte)record[i];
+ for (unsigned i = 0; i < kRecordSize; i++)
+ sum += (Byte)record[i];
}
- /* we use GNU TAR scheme:
- checksum field is formatted differently from the
+ /* checksum field is formatted differently from the
other fields: it has [6] digits, a null, then a space. */
- // WRITE_OCTAL_8_CHECK(record + 148, checkSum);
+ // WRITE_OCTAL_8_CHECK(record + 148, sum);
const unsigned kNumDigits = 6;
for (unsigned i = 0; i < kNumDigits; i++)
{
- record[148 + kNumDigits - 1 - i] = (char)('0' + (checkSum & 7));
- checkSum >>= 3;
+ record[148 + kNumDigits - 1 - i] = (char)('0' + (sum & 7));
+ sum >>= 3;
}
- record[148 + 6] = 0;
+ // record[148 + 6] = 0; // we need it, if we use memset(' ') init
+ record[148 + 7] = ' '; // we need it, if we use binary init
}
- RINOK(WriteBytes(record, NFileHeader::kRecordSize));
+ RINOK(Write_Data(record, kRecordSize));
- if (item.IsSparse())
+ if (item.Is_Sparse())
{
for (unsigned i = 4; i < item.SparseBlocks.Size();)
{
- memset(record, 0, NFileHeader::kRecordSize);
+ memset(record, 0, kRecordSize);
for (unsigned t = 0; t < 21 && i < item.SparseBlocks.Size(); t++, i++)
{
const CSparseBlock &sb = item.SparseBlocks[i];
@@ -169,7 +209,7 @@ HRESULT COutArchive::WriteHeaderReal(const CItem &item)
WriteOctal_12(p + 12, sb.Size);
}
record[21 * 24] = (char)(i < item.SparseBlocks.Size() ? 1 : 0);
- RINOK(WriteBytes(record, NFileHeader::kRecordSize));
+ RINOK(Write_Data(record, kRecordSize));
}
}
@@ -177,101 +217,426 @@ HRESULT COutArchive::WriteHeaderReal(const CItem &item)
}
-/* OLD_GNU_TAR: writes short name with zero at the end
- NEW_GNU_TAR: writes short name without zero at the end */
+static void AddPaxLine(AString &s, const char *name, const AString &val)
+{
+ // s.Add_LF(); // for debug
+ const unsigned len = 3 + (unsigned)strlen(name) + val.Len();
+ AString n;
+ for (unsigned numDigits = 1;; numDigits++)
+ {
+ n.Empty();
+ n.Add_UInt32(numDigits + len);
+ if (numDigits == n.Len())
+ break;
+ }
+ s += n;
+ s.Add_Space();
+ s += name;
+ s += '=';
+ s += val;
+ s.Add_LF();
+}
+
+
+static void AddPaxTime(AString &s, const char *name, const CPaxTime &pt,
+ const CTimeOptions &options)
+{
+ unsigned numDigits = pt.NumDigits;
+ if (numDigits > options.NumDigitsMax)
+ numDigits = options.NumDigitsMax;
+
+ bool needNs = false;
+ UInt32 ns = 0;
+ if (numDigits != 0)
+ {
+ ns = pt.Ns;
+ // if (ns != 0) before reduction, we show all digits after digits reduction
+ needNs = (ns != 0 || options.RemoveZeroMode == k_PaxTimeMode_DontRemoveZero);
+ UInt32 d = 1;
+ for (unsigned k = numDigits; k < 9; k++)
+ d *= 10;
+ ns /= d;
+ ns *= d;
+ }
+
+ AString v;
+ {
+ Int64 sec = pt.Sec;
+ if (pt.Sec < 0)
+ {
+ sec = -sec;
+ v += '-';
+ if (ns != 0)
+ {
+ ns = 1000*1000*1000 - ns;
+ sec--;
+ }
+ }
+ v.Add_UInt64(sec);
+ }
+
+ if (needNs)
+ {
+ AString d;
+ d.Add_UInt32(ns);
+ while (d.Len() < 9)
+ d.InsertAtFront('0');
+ // here we have precision
+ while (d.Len() > (unsigned)numDigits)
+ d.DeleteBack();
+ // GNU TAR reduces '0' digits.
+ if (options.RemoveZeroMode == k_PaxTimeMode_RemoveZero_Always)
+ while (!d.IsEmpty() && d.Back() == '0')
+ d.DeleteBack();
+
+ if (!d.IsEmpty())
+ {
+ v += '.';
+ v += d;
+ // v += "1234567009999"; // for debug
+ // for (int y = 0; y < 1000; y++) v += '8'; // for debug
+ }
+ }
+
+ AddPaxLine(s, name, v);
+}
+
+
+static void AddPax_UInt32_ifBig(AString &s, const char *name, const UInt32 &v)
+{
+ if (v > k_7_oct_digits_Val_Max)
+ {
+ AString s2;
+ s2.Add_UInt32(v);
+ AddPaxLine(s, name, s2);
+ }
+}
+
+
+/* OLD_GNU_TAR: writes name with zero at the end
+ NEW_GNU_TAR: can write name filled with all kNameSize characters */
static const unsigned kNameSize_Max =
- NFileHeader::kNameSize; // NEW_GNU_TAR / 7-Zip 21.07
- // NFileHeader::kNameSize - 1; // OLD_GNU_TAR / old 7-Zip
+ kNameSize; // NEW_GNU_TAR / 7-Zip 21.07
+ // kNameSize - 1; // OLD_GNU_TAR / old 7-Zip
#define DOES_NAME_FIT_IN_FIELD(name) ((name).Len() <= kNameSize_Max)
+
HRESULT COutArchive::WriteHeader(const CItem &item)
{
- if (DOES_NAME_FIT_IN_FIELD(item.Name) &&
- DOES_NAME_FIT_IN_FIELD(item.LinkName))
- return WriteHeaderReal(item);
+ Glob_Name.Empty();
+ Prefix.Empty();
- // here we can get all fields from main (item) or create new empty item
- /*
- CItem mi;
- mi.SetDefaultWriteFields();
- */
-
- CItem mi = item;
- mi.LinkName.Empty();
- // SparseBlocks will be ignored by IsSparse()
- // mi.SparseBlocks.Clear();
+ unsigned namePos = 0;
+ bool needPathCut = false;
+ bool allowPrefix = false;
+
+ if (!DOES_NAME_FIT_IN_FIELD(item.Name))
+ {
+ const char *s = item.Name;
+ const char *p = s + item.Name.Len() - 1;
+ for (; *p == '/' && p != s; p--)
+ {}
+ for (; p != s && p[-1] != '/'; p--)
+ {}
+ namePos = (unsigned)(p - s);
+ needPathCut = true;
+ }
- mi.Name = NFileHeader::kLongLink;
- // 21.07 : we set Mode and MTime props as in GNU TAR:
- mi.Mode = 0644; // octal
- mi.MTime = 0;
+ if (IsPosixMode)
+ {
+ AString s;
+
+ if (needPathCut)
+ {
+ const unsigned nameLen = item.Name.Len() - namePos;
+ if ( item.LinkFlag >= NLinkFlag::kNormal
+ && item.LinkFlag <= NLinkFlag::kDirectory
+ && namePos > 1
+ && nameLen != 0
+ // && IsPrefixAllowed
+ && item.IsMagic_Posix_ustar_00())
+ {
+ /* GNU TAR decoder supports prefix field, only if (magic)
+ signature matches 6-bytes "ustar\0".
+ so here we use prefix field only in posix mode with posix signature */
+
+ allowPrefix = true;
+ // allowPrefix = false; // for debug
+ if (namePos <= kPrefixSize + 1 && nameLen <= kNameSize_Max)
+ {
+ needPathCut = false;
+ /* we will set Prefix and Glob_Name later, for such conditions:
+ if (!DOES_NAME_FIT_IN_FIELD(item.Name) && !needPathCut) */
+ }
+ }
- for (int i = 0; i < 2; i++)
+ if (needPathCut)
+ AddPaxLine(s, "path", item.Name);
+ }
+
+ // AddPaxLine(s, "testname", AString("testval")); // for debug
+
+ if (item.LinkName.Len() > kNameSize_Max)
+ AddPaxLine(s, "linkpath", item.LinkName);
+
+ const UInt64 kPaxSize_Limit = ((UInt64)1 << 33);
+ // const UInt64 kPaxSize_Limit = ((UInt64)1 << 1); // for debug
+ // bool zero_PackSize = false;
+ if (item.PackSize >= kPaxSize_Limit)
+ {
+ /* GNU TAR in pax mode sets PackSize = 0 in main record, if pack_size >= 8 GiB
+ But old 7-Zip doesn't detect "size" property from pax header.
+ So we write real size (>= 8 GiB) to main record in binary format,
+ and old 7-Zip can decode size correctly */
+ // zero_PackSize = true;
+ AString v;
+ v.Add_UInt64(item.PackSize);
+ AddPaxLine(s, "size", v);
+ }
+
+ /* GNU TAR encoder can set "devmajor" / "devminor" attributes,
+ but GNU TAR decoder doesn't parse "devmajor" / "devminor" */
+ if (item.DeviceMajor_Defined)
+ AddPax_UInt32_ifBig(s, "devmajor", item.DeviceMajor);
+ if (item.DeviceMinor_Defined)
+ AddPax_UInt32_ifBig(s, "devminor", item.DeviceMinor);
+
+ AddPax_UInt32_ifBig(s, "uid", item.UID);
+ AddPax_UInt32_ifBig(s, "gid", item.GID);
+
+ const UInt64 kPax_MTime_Limit = ((UInt64)1 << 33);
+ const bool zero_MTime = (
+ item.MTime < 0 ||
+ item.MTime >= (Int64)kPax_MTime_Limit);
+
+ const CPaxTime &mtime = item.PaxTimes.MTime;
+ if (mtime.IsDefined())
+ {
+ bool needPax = false;
+ if (zero_MTime)
+ needPax = true;
+ else if (TimeOptions.NumDigitsMax > 0)
+ if (mtime.Ns != 0 ||
+ (mtime.NumDigits != 0 &&
+ TimeOptions.RemoveZeroMode == k_PaxTimeMode_DontRemoveZero))
+ needPax = true;
+ if (needPax)
+ AddPaxTime(s, "mtime", mtime, TimeOptions);
+ }
+
+ if (item.PaxTimes.ATime.IsDefined())
+ AddPaxTime(s, "atime", item.PaxTimes.ATime, TimeOptions);
+ if (item.PaxTimes.CTime.IsDefined())
+ AddPaxTime(s, "ctime", item.PaxTimes.CTime, TimeOptions);
+
+ if (item.User.Len() > kUserNameSize)
+ AddPaxLine(s, "uname", item.User);
+ if (item.Group.Len() > kGroupNameSize)
+ AddPaxLine(s, "gname", item.Group);
+
+ /*
+ // for debug
+ AString a ("11"); for (int y = 0; y < (1 << 24); y++) AddPaxLine(s, "temp", a);
+ */
+
+ const unsigned paxSize = s.Len();
+ if (paxSize != 0)
+ {
+ CItem mi = item;
+ mi.LinkName.Empty();
+ // SparseBlocks will be ignored by Is_Sparse()
+ // mi.SparseBlocks.Clear();
+ // we use "PaxHeader/*" for compatibility with previous 7-Zip decoder
+
+ // GNU TAR writes empty for these fields;
+ mi.User.Empty();
+ mi.Group.Empty();
+ mi.UID = 0;
+ mi.GID = 0;
+
+ mi.DeviceMajor_Defined = false;
+ mi.DeviceMinor_Defined = false;
+
+ mi.Name = "PaxHeader/@PaxHeader";
+ mi.Mode = 0644; // octal
+ if (zero_MTime)
+ mi.MTime = 0;
+ mi.LinkFlag = NLinkFlag::kPax;
+ // mi.LinkFlag = 'Z'; // for debug
+ mi.PackSize = paxSize;
+ // for (unsigned y = 0; y < 1; y++) { // for debug
+ RINOK(WriteHeaderReal(mi, true)); // isPax
+ RINOK(Write_Data_And_Residual(s, paxSize));
+ // } // for debug
+ /*
+ we can send (zero_MTime) for compatibility with gnu tar output.
+ we can send (zero_MTime = false) for better compatibility with old 7-Zip
+ */
+ // return WriteHeaderReal(item);
+ /*
+ false, // isPax
+ false, // zero_PackSize
+ false); // zero_MTime
+ */
+ }
+ }
+ else // !PosixMode
+ if (!DOES_NAME_FIT_IN_FIELD(item.Name) ||
+ !DOES_NAME_FIT_IN_FIELD(item.LinkName))
{
- const AString *name;
- // We suppose that GNU TAR also writes item for long link before item for LongName?
- if (i == 0)
+ // here we can get all fields from main (item) or create new empty item
+ /*
+ CItem mi;
+ mi.SetDefaultWriteFields();
+ */
+ CItem mi = item;
+ mi.LinkName.Empty();
+ // SparseBlocks will be ignored by Is_Sparse()
+ // mi.SparseBlocks.Clear();
+ mi.Name = kLongLink;
+ // mi.Name = "././@BAD_LONG_LINK_TEST"; // for debug
+ // 21.07 : we set Mode and MTime props as in GNU TAR:
+ mi.Mode = 0644; // octal
+ mi.MTime = 0;
+
+ mi.User.Empty();
+ mi.Group.Empty();
+ /*
+ gnu tar sets "root" for such items:
+ uid_to_uname (0, &uname);
+ gid_to_gname (0, &gname);
+ */
+ /*
+ mi.User = "root";
+ mi.Group = "root";
+ */
+ mi.UID = 0;
+ mi.GID = 0;
+ mi.DeviceMajor_Defined = false;
+ mi.DeviceMinor_Defined = false;
+
+
+ for (unsigned i = 0; i < 2; i++)
{
- mi.LinkFlag = NFileHeader::NLinkFlag::kGnu_LongLink;
- name = &item.LinkName;
+ const AString *name;
+ // We suppose that GNU TAR also writes item for long link before item for LongName?
+ if (i == 0)
+ {
+ mi.LinkFlag = NLinkFlag::kGnu_LongLink;
+ name = &item.LinkName;
+ }
+ else
+ {
+ mi.LinkFlag = NLinkFlag::kGnu_LongName;
+ name = &item.Name;
+ }
+ if (DOES_NAME_FIT_IN_FIELD(*name))
+ continue;
+ // GNU TAR writes null character after NAME to file. We do same here:
+ const unsigned nameStreamSize = name->Len() + 1;
+ mi.PackSize = nameStreamSize;
+ // for (unsigned y = 0; y < 3; y++) { // for debug
+ RINOK(WriteHeaderReal(mi));
+ RINOK(Write_Data_And_Residual(name->Ptr(), nameStreamSize));
+ // }
+
+ // for debug
+ /*
+ const unsigned kSize = (1 << 29) + 16;
+ CByteBuffer buf;
+ buf.Alloc(kSize);
+ memset(buf, 0, kSize);
+ memcpy(buf, name->Ptr(), name->Len());
+ const unsigned nameStreamSize = kSize;
+ mi.PackSize = nameStreamSize;
+ // for (unsigned y = 0; y < 3; y++) { // for debug
+ RINOK(WriteHeaderReal(mi));
+ RINOK(WriteBytes(buf, nameStreamSize));
+ RINOK(FillDataResidual(nameStreamSize));
+ */
}
+ }
+
+ // bool fals = false; if (fals) // for debug: for bit-to-bit output compatibility with GNU TAR
+
+ if (!DOES_NAME_FIT_IN_FIELD(item.Name))
+ {
+ const unsigned nameLen = item.Name.Len() - namePos;
+ if (!needPathCut)
+ Prefix.SetFrom(item.Name, namePos - 1);
else
{
- mi.LinkFlag = NFileHeader::NLinkFlag::kGnu_LongName;
- name = &item.Name;
+ Glob_Name = K_PREFIX_PATH_CUT "/_pc_";
+
+ if (namePos == 0)
+ Glob_Name += "root";
+ else
+ {
+ Glob_Name += "crc32/";
+ char temp[12];
+ ConvertUInt32ToHex8Digits(CrcCalc(item.Name, namePos - 1), temp);
+ Glob_Name += temp;
+ }
+
+ if (!allowPrefix || Glob_Name.Len() + 1 + nameLen <= kNameSize_Max)
+ Glob_Name.Add_Slash();
+ else
+ {
+ Prefix = Glob_Name;
+ Glob_Name.Empty();
+ }
}
- if (DOES_NAME_FIT_IN_FIELD(*name))
- continue;
- // GNU TAR writes null character after NAME to file. We do same here:
- const unsigned nameStreamSize = name->Len() + 1;
- mi.PackSize = nameStreamSize;
- RINOK(WriteHeaderReal(mi));
- RINOK(WriteBytes(name->Ptr(), nameStreamSize));
- RINOK(FillDataResidual(nameStreamSize));
+ Glob_Name.AddFrom(item.Name.Ptr(namePos), nameLen);
}
- // 21.07: WriteHeaderReal() writes short part of (Name) and (LinkName).
return WriteHeaderReal(item);
- /*
- mi = item;
- if (!DOES_NAME_FIT_IN_FIELD(mi.Name))
- mi.Name.SetFrom(item.Name, kNameSize_Max);
- if (!DOES_NAME_FIT_IN_FIELD(mi.LinkName))
- mi.LinkName.SetFrom(item.LinkName, kNameSize_Max);
- return WriteHeaderReal(mi);
- */
}
-HRESULT COutArchive::FillDataResidual(UInt64 dataSize)
+
+HRESULT COutArchive::Write_Data(const void *data, unsigned size)
{
- unsigned lastRecordSize = ((unsigned)dataSize & (NFileHeader::kRecordSize - 1));
- if (lastRecordSize == 0)
+ Pos += size;
+ return WriteStream(Stream, data, size);
+}
+
+HRESULT COutArchive::Write_AfterDataResidual(UInt64 dataSize)
+{
+ const unsigned v = ((unsigned)dataSize & (kRecordSize - 1));
+ if (v == 0)
return S_OK;
- unsigned rem = NFileHeader::kRecordSize - lastRecordSize;
- Byte buf[NFileHeader::kRecordSize];
+ const unsigned rem = kRecordSize - v;
+ Byte buf[kRecordSize];
memset(buf, 0, rem);
- return WriteBytes(buf, rem);
+ return Write_Data(buf, rem);
+}
+
+
+HRESULT COutArchive::Write_Data_And_Residual(const void *data, unsigned size)
+{
+ RINOK(Write_Data(data, size));
+ return Write_AfterDataResidual(size);
}
+
HRESULT COutArchive::WriteFinishHeader()
{
- Byte record[NFileHeader::kRecordSize];
- memset(record, 0, NFileHeader::kRecordSize);
+ Byte record[kRecordSize];
+ memset(record, 0, kRecordSize);
const unsigned kNumFinishRecords = 2;
/* GNU TAR by default uses --blocking-factor=20 (512 * 20 = 10 KiB)
we also can use cluster alignment:
- const unsigned numBlocks = (unsigned)(Pos / NFileHeader::kRecordSize) + kNumFinishRecords;
+ const unsigned numBlocks = (unsigned)(Pos / kRecordSize) + kNumFinishRecords;
const unsigned kNumClusterBlocks = (1 << 3); // 8 blocks = 4 KiB
const unsigned numFinishRecords = kNumFinishRecords + ((kNumClusterBlocks - numBlocks) & (kNumClusterBlocks - 1));
*/
for (unsigned i = 0; i < kNumFinishRecords; i++)
{
- RINOK(WriteBytes(record, NFileHeader::kRecordSize));
+ RINOK(Write_Data(record, kRecordSize));
}
return S_OK;
}
diff --git a/CPP/7zip/Archive/Tar/TarOut.h b/CPP/7zip/Archive/Tar/TarOut.h
index ee9b965e..34af20ac 100644..100755
--- a/CPP/7zip/Archive/Tar/TarOut.h
+++ b/CPP/7zip/Archive/Tar/TarOut.h
@@ -14,21 +14,38 @@ namespace NTar {
class COutArchive
{
- CMyComPtr<ISequentialOutStream> m_Stream;
+ CMyComPtr<ISequentialOutStream> Stream;
+
+ AString Glob_Name;
+ AString Prefix;
+
+ HRESULT WriteHeaderReal(const CItem &item, bool isPax = false
+ // , bool zero_PackSize = false
+ // , bool zero_MTime = false
+ );
+
+ HRESULT Write_Data(const void *data, unsigned size);
+ HRESULT Write_Data_And_Residual(const void *data, unsigned size);
- HRESULT WriteBytes(const void *data, unsigned size);
- HRESULT WriteHeaderReal(const CItem &item);
public:
UInt64 Pos;
-
+ bool IsPosixMode;
+ // bool IsPrefixAllowed; // it's used only if (IsPosixMode == true)
+ CTimeOptions TimeOptions;
+
void Create(ISequentialOutStream *outStream)
{
- m_Stream = outStream;
+ Stream = outStream;
}
-
HRESULT WriteHeader(const CItem &item);
- HRESULT FillDataResidual(UInt64 dataSize);
+ HRESULT Write_AfterDataResidual(UInt64 dataSize);
HRESULT WriteFinishHeader();
+
+ COutArchive():
+ Pos(0),
+ IsPosixMode(false)
+ // , IsPrefixAllowed(true)
+ {}
};
}}
diff --git a/CPP/7zip/Archive/Tar/TarRegister.cpp b/CPP/7zip/Archive/Tar/TarRegister.cpp
index 5014f04d..a78c3766 100644..100755
--- a/CPP/7zip/Archive/Tar/TarRegister.cpp
+++ b/CPP/7zip/Archive/Tar/TarRegister.cpp
@@ -15,9 +15,17 @@ REGISTER_ARC_IO(
"tar", "tar ova", 0, 0xEE,
k_Signature,
NFileHeader::kUstarMagic_Offset,
- NArcInfoFlags::kStartOpen |
- NArcInfoFlags::kSymLinks |
- NArcInfoFlags::kHardLinks,
- IsArc_Tar)
+ NArcInfoFlags::kStartOpen
+ | NArcInfoFlags::kSymLinks
+ | NArcInfoFlags::kHardLinks
+ | NArcInfoFlags::kMTime
+ | NArcInfoFlags::kMTime_Default
+ // | NArcInfoTimeFlags::kCTime
+ // | NArcInfoTimeFlags::kATime
+ , TIME_PREC_TO_ARC_FLAGS_MASK (NFileTimeType::kWindows)
+ | TIME_PREC_TO_ARC_FLAGS_MASK (NFileTimeType::kUnix)
+ | TIME_PREC_TO_ARC_FLAGS_MASK (NFileTimeType::k1ns)
+ | TIME_PREC_TO_ARC_FLAGS_TIME_DEFAULT (NFileTimeType::kUnix)
+ , IsArc_Tar)
}}
diff --git a/CPP/7zip/Archive/Tar/TarUpdate.cpp b/CPP/7zip/Archive/Tar/TarUpdate.cpp
index 295e16bb..caa0a822 100644..100755
--- a/CPP/7zip/Archive/Tar/TarUpdate.cpp
+++ b/CPP/7zip/Archive/Tar/TarUpdate.cpp
@@ -2,6 +2,8 @@
#include "StdAfx.h"
+// #include <stdio.h>
+
#include "../../../Windows/TimeUtils.h"
#include "../../Common/LimitedStreams.h"
@@ -15,18 +17,161 @@
namespace NArchive {
namespace NTar {
+static void FILETIME_To_PaxTime(const FILETIME &ft, CPaxTime &pt)
+{
+ UInt32 ns;
+ pt.Sec = NWindows::NTime::FileTime_To_UnixTime64_and_Quantums(ft, ns);
+ pt.Ns = ns * 100;
+ pt.NumDigits = 7;
+}
+
+
+HRESULT Prop_To_PaxTime(const NWindows::NCOM::CPropVariant &prop, CPaxTime &pt)
+{
+ pt.Clear();
+ if (prop.vt == VT_EMPTY)
+ {
+ // pt.Sec = 0;
+ return S_OK;
+ }
+ if (prop.vt != VT_FILETIME)
+ return E_INVALIDARG;
+ {
+ UInt32 ns;
+ pt.Sec = NWindows::NTime::FileTime_To_UnixTime64_and_Quantums(prop.filetime, ns);
+ ns *= 100;
+ pt.NumDigits = 7;
+ const unsigned prec = prop.wReserved1;
+ if (prec >= k_PropVar_TimePrec_Base)
+ {
+ pt.NumDigits = prec - k_PropVar_TimePrec_Base;
+ if (prop.wReserved2 < 100)
+ ns += prop.wReserved2;
+ }
+ pt.Ns = ns;
+ return S_OK;
+ }
+}
+
+
+static HRESULT GetTime(IStreamGetProp *getProp, UInt32 pid, CPaxTime &pt)
+{
+ pt.Clear();
+ NWindows::NCOM::CPropVariant prop;
+ RINOK(getProp->GetProperty(pid, &prop));
+ return Prop_To_PaxTime(prop, pt);
+}
+
+
+static HRESULT GetUser(IStreamGetProp *getProp,
+ UInt32 pidName, UInt32 pidId, AString &name, UInt32 &id,
+ UINT codePage, unsigned utfFlags)
+{
+ // printf("\nGetUser\n");
+ // we keep old values, if both GetProperty() return VT_EMPTY
+ // we clear old values, if any of GetProperty() returns non-VT_EMPTY;
+ bool isSet = false;
+ {
+ NWindows::NCOM::CPropVariant prop;
+ RINOK(getProp->GetProperty(pidId, &prop));
+ if (prop.vt == VT_UI4)
+ {
+ isSet = true;
+ id = prop.ulVal;
+ name.Empty();
+ }
+ else if (prop.vt != VT_EMPTY)
+ return E_INVALIDARG;
+ }
+ {
+ NWindows::NCOM::CPropVariant prop;
+ RINOK(getProp->GetProperty(pidName, &prop));
+ if (prop.vt == VT_BSTR)
+ {
+ const UString s = prop.bstrVal;
+ Get_AString_From_UString(s, name, codePage, utfFlags);
+ // printf("\ngetProp->GetProperty(pidName, &prop) : %s" , name.Ptr());
+ if (!isSet)
+ id = 0;
+ }
+ else if (prop.vt == VT_UI4)
+ {
+ id = prop.ulVal;
+ name.Empty();
+ }
+ else if (prop.vt != VT_EMPTY)
+ return E_INVALIDARG;
+ }
+ return S_OK;
+}
+
+
+/*
+static HRESULT GetDevice(IStreamGetProp *getProp,
+ UInt32 &majo, UInt32 &mino, bool &majo_defined, bool &mino_defined)
+{
+ NWindows::NCOM::CPropVariant prop;
+ RINOK(getProp->GetProperty(kpidDevice, &prop));
+ if (prop.vt == VT_EMPTY)
+ return S_OK;
+ if (prop.vt != VT_UI8)
+ return E_INVALIDARG;
+ {
+ printf("\nTarUpdate.cpp :: GetDevice()\n");
+ const UInt64 v = prop.uhVal.QuadPart;
+ majo = MY_dev_major(v);
+ mino = MY_dev_minor(v);
+ majo_defined = true;
+ mino_defined = true;
+ }
+ return S_OK;
+}
+*/
+
+static HRESULT GetDevice(IStreamGetProp *getProp,
+ UInt32 pid, UInt32 &id, bool &defined)
+{
+ defined = false;
+ NWindows::NCOM::CPropVariant prop;
+ RINOK(getProp->GetProperty(pid, &prop));
+ if (prop.vt == VT_EMPTY)
+ return S_OK;
+ if (prop.vt == VT_UI4)
+ {
+ id = prop.ulVal;
+ defined = true;
+ return S_OK;
+ }
+ return E_INVALIDARG;
+}
+
+
HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
const CObjectVector<NArchive::NTar::CItemEx> &inputItems,
const CObjectVector<CUpdateItem> &updateItems,
- UINT codePage, unsigned utfFlags,
+ const CUpdateOptions &options,
IArchiveUpdateCallback *updateCallback)
{
COutArchive outArchive;
outArchive.Create(outStream);
outArchive.Pos = 0;
+ outArchive.IsPosixMode = options.PosixMode;
+ outArchive.TimeOptions = options.TimeOptions;
CMyComPtr<IOutStream> outSeekStream;
outStream->QueryInterface(IID_IOutStream, (void **)&outSeekStream);
+ if (outSeekStream)
+ {
+ /*
+ // for debug
+ Byte buf[1 << 14];
+ memset (buf, 0, sizeof(buf));
+ RINOK(outStream->Write(buf, sizeof(buf), NULL));
+ */
+ // we need real outArchive.Pos, if outSeekStream->SetSize() will be used.
+ RINOK(outSeekStream->Seek(0, STREAM_SEEK_CUR, &outArchive.Pos));
+ }
+
CMyComPtr<IArchiveUpdateCallbackFile> opCallback;
updateCallback->QueryInterface(IID_IArchiveUpdateCallbackFile, (void **)&opCallback);
@@ -40,7 +185,7 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
if (ui.NewData)
complexity += ui.Size;
else
- complexity += inputItems[(unsigned)ui.IndexInArc].GetFullSize();
+ complexity += inputItems[(unsigned)ui.IndexInArc].Get_FullSize_Aligned();
}
RINOK(updateCallback->SetTotal(complexity));
@@ -58,21 +203,31 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
complexity = 0;
- for (i = 0; i < updateItems.Size(); i++)
+ // const int kNumReduceDigits = -1; // for debug
+
+ for (i = 0;; i++)
{
lps->InSize = lps->OutSize = complexity;
RINOK(lps->SetCur());
+ if (i == updateItems.Size())
+ return outArchive.WriteFinishHeader();
+
const CUpdateItem &ui = updateItems[i];
CItem item;
if (ui.NewProps)
{
- item.SetDefaultWriteFields();
- item.Mode = ui.Mode;
+ item.SetMagic_Posix(options.PosixMode);
item.Name = ui.Name;
item.User = ui.User;
item.Group = ui.Group;
+ item.UID = ui.UID;
+ item.GID = ui.GID;
+ item.DeviceMajor = ui.DeviceMajor;
+ item.DeviceMinor = ui.DeviceMinor;
+ item.DeviceMajor_Defined = ui.DeviceMajor_Defined;
+ item.DeviceMinor_Defined = ui.DeviceMinor_Defined;
if (ui.IsDir)
{
@@ -81,11 +236,15 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
}
else
{
- item.LinkFlag = NFileHeader::NLinkFlag::kNormal;
item.PackSize = ui.Size;
+ item.Set_LinkFlag_for_File(ui.Mode);
}
-
- item.MTime = ui.MTime;
+
+ // 22.00
+ item.Mode = ui.Mode & ~(UInt32)MY_LIN_S_IFMT;
+ item.PaxTimes = ui.PaxTimes;
+ // item.PaxTimes.ReducePrecison(kNumReduceDigits); // for debug
+ item.MTime = ui.PaxTimes.MTime.GetSec();
}
else
item = inputItems[(unsigned)ui.IndexInArc];
@@ -93,7 +252,8 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
AString symLink;
if (ui.NewData || ui.NewProps)
{
- RINOK(GetPropString(updateCallback, ui.IndexInClient, kpidSymLink, symLink, codePage, utfFlags, true));
+ RINOK(GetPropString(updateCallback, ui.IndexInClient, kpidSymLink, symLink,
+ options.CodePage, options.UtfFlags, true));
if (!symLink.IsEmpty())
{
item.LinkFlag = NFileHeader::NLinkFlag::kSymLink;
@@ -120,7 +280,7 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
}
else
{
- HRESULT res = updateCallback->GetStream(ui.IndexInClient, &fileInStream);
+ const HRESULT res = updateCallback->GetStream(ui.IndexInClient, &fileInStream);
if (res == S_FALSE)
needWrite = false;
@@ -128,31 +288,105 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
{
RINOK(res);
- if (fileInStream)
+ if (!fileInStream)
+ {
+ item.PackSize = 0;
+ item.Size = 0;
+ }
+ else
{
CMyComPtr<IStreamGetProps> getProps;
- fileInStream->QueryInterface(IID_IStreamGetProps, (void **)&getProps);
- if (getProps)
+ CMyComPtr<IStreamGetProp> getProp;
+ fileInStream->QueryInterface(IID_IStreamGetProp, (void **)&getProp);
+ if (getProp)
+ {
+ if (options.Write_MTime.Val) RINOK(GetTime(getProp, kpidMTime, item.PaxTimes.MTime))
+ if (options.Write_ATime.Val) RINOK(GetTime(getProp, kpidATime, item.PaxTimes.ATime))
+ if (options.Write_CTime.Val) RINOK(GetTime(getProp, kpidCTime, item.PaxTimes.CTime))
+
+ if (options.PosixMode)
+ {
+ /*
+ RINOK(GetDevice(getProp, item.DeviceMajor, item.DeviceMinor,
+ item.DeviceMajor_Defined, item.DeviceMinor_Defined));
+ */
+ bool defined = false;
+ UInt32 val = 0;
+ RINOK(GetDevice(getProp, kpidDeviceMajor, val, defined));
+ if (defined)
+ {
+ item.DeviceMajor = val;
+ item.DeviceMajor_Defined = true;
+ item.DeviceMinor = 0;
+ item.DeviceMinor_Defined = false;
+ RINOK(GetDevice(getProp, kpidDeviceMinor, item.DeviceMinor, item.DeviceMinor_Defined));
+ }
+ }
+
+ RINOK(GetUser(getProp, kpidUser, kpidUserId, item.User, item.UID, options.CodePage, options.UtfFlags));
+ RINOK(GetUser(getProp, kpidGroup, kpidGroupId, item.Group, item.GID, options.CodePage, options.UtfFlags));
+
+ {
+ NWindows::NCOM::CPropVariant prop;
+ RINOK(getProp->GetProperty(kpidPosixAttrib, &prop));
+ if (prop.vt == VT_EMPTY)
+ item.Mode =
+ MY_LIN_S_IRWXO
+ | MY_LIN_S_IRWXG
+ | MY_LIN_S_IRWXU
+ | (ui.IsDir ? MY_LIN_S_IFDIR : MY_LIN_S_IFREG);
+ else if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ else
+ item.Mode = prop.ulVal;
+ // 21.07 : we clear high file type bits as GNU TAR.
+ item.Set_LinkFlag_for_File(item.Mode);
+ item.Mode &= ~(UInt32)MY_LIN_S_IFMT;
+ }
+
+ {
+ NWindows::NCOM::CPropVariant prop;
+ RINOK(getProp->GetProperty(kpidSize, &prop));
+ if (prop.vt != VT_UI8)
+ return E_INVALIDARG;
+ const UInt64 size = prop.uhVal.QuadPart;
+ item.PackSize = size;
+ item.Size = size;
+ }
+ /*
+ printf("\nNum digits = %d %d\n",
+ (int)item.PaxTimes.MTime.NumDigits,
+ (int)item.PaxTimes.MTime.Ns);
+ */
+ }
+ else
{
- FILETIME mTime;
- UInt64 size2;
- if (getProps->GetProps(&size2, NULL, NULL, &mTime, NULL) == S_OK)
+ fileInStream->QueryInterface(IID_IStreamGetProps, (void **)&getProps);
+ if (getProps)
{
- item.PackSize = size2;
- item.Size = size2;
- item.MTime = NWindows::NTime::FileTimeToUnixTime64(mTime);;
+ FILETIME mTime, aTime, cTime;
+ UInt64 size2;
+ if (getProps->GetProps(&size2,
+ options.Write_CTime.Val ? &cTime : NULL,
+ options.Write_ATime.Val ? &aTime : NULL,
+ options.Write_MTime.Val ? &mTime : NULL,
+ NULL) == S_OK)
+ {
+ item.PackSize = size2;
+ item.Size = size2;
+ if (options.Write_MTime.Val) FILETIME_To_PaxTime(mTime, item.PaxTimes.MTime);
+ if (options.Write_ATime.Val) FILETIME_To_PaxTime(aTime, item.PaxTimes.ATime);
+ if (options.Write_CTime.Val) FILETIME_To_PaxTime(cTime, item.PaxTimes.CTime);
+ }
}
}
}
- else
- {
- item.PackSize = 0;
- item.Size = 0;
- }
{
+ // we must request kpidHardLink after updateCallback->GetStream()
AString hardLink;
- RINOK(GetPropString(updateCallback, ui.IndexInClient, kpidHardLink, hardLink, codePage, utfFlags, true));
+ RINOK(GetPropString(updateCallback, ui.IndexInClient, kpidHardLink, hardLink,
+ options.CodePage, options.UtfFlags, true));
if (!hardLink.IsEmpty())
{
item.LinkFlag = NFileHeader::NLinkFlag::kHardLink;
@@ -165,37 +399,98 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
}
}
+ // item.PaxTimes.ReducePrecison(kNumReduceDigits); // for debug
+
+ if (ui.NewProps)
+ item.MTime = item.PaxTimes.MTime.GetSec();
+
if (needWrite)
{
- UInt64 fileHeaderStartPos = outArchive.Pos;
+ const UInt64 headerPos = outArchive.Pos;
+ // item.PackSize = ((UInt64)1 << 33); // for debug
RINOK(outArchive.WriteHeader(item));
if (fileInStream)
{
- RINOK(copyCoder->Code(fileInStream, outStream, NULL, NULL, progress));
- outArchive.Pos += copyCoderSpec->TotalSize;
- if (copyCoderSpec->TotalSize != item.PackSize)
+ for (unsigned numPasses = 0;; numPasses++)
{
+ /* we support 2 attempts to write header:
+ pass-0: main pass:
+ pass-1: additional pass, if size_of_file and size_of_header are changed */
+ if (numPasses >= 2)
+ {
+ // opRes = NArchive::NUpdate::NOperationResult::kError_FileChanged;
+ // break;
+ return E_FAIL;
+ }
+
+ const UInt64 dataPos = outArchive.Pos;
+ RINOK(copyCoder->Code(fileInStream, outStream, NULL, NULL, progress));
+ outArchive.Pos += copyCoderSpec->TotalSize;
+ RINOK(outArchive.Write_AfterDataResidual(copyCoderSpec->TotalSize));
+
+ // if (numPasses >= 10) // for debug
+ if (copyCoderSpec->TotalSize == item.PackSize)
+ break;
+
+ if (opCallback)
+ {
+ RINOK(opCallback->ReportOperation(
+ NEventIndexType::kOutArcIndex, (UInt32)ui.IndexInClient,
+ NUpdateNotifyOp::kInFileChanged))
+ }
+
if (!outSeekStream)
return E_FAIL;
- UInt64 backOffset = outArchive.Pos - fileHeaderStartPos;
- RINOK(outSeekStream->Seek(-(Int64)backOffset, STREAM_SEEK_CUR, NULL));
- outArchive.Pos = fileHeaderStartPos;
+ const UInt64 nextPos = outArchive.Pos;
+ RINOK(outSeekStream->Seek(-(Int64)(nextPos - headerPos), STREAM_SEEK_CUR, NULL));
+ outArchive.Pos = headerPos;
item.PackSize = copyCoderSpec->TotalSize;
+
RINOK(outArchive.WriteHeader(item));
- RINOK(outSeekStream->Seek((Int64)item.PackSize, STREAM_SEEK_CUR, NULL));
- outArchive.Pos += item.PackSize;
+
+ // if (numPasses >= 10) // for debug
+ if (outArchive.Pos == dataPos)
+ {
+ const UInt64 alignedSize = nextPos - dataPos;
+ if (alignedSize != 0)
+ {
+ RINOK(outSeekStream->Seek(alignedSize, STREAM_SEEK_CUR, NULL));
+ outArchive.Pos += alignedSize;
+ }
+ break;
+ }
+
+ // size of header was changed.
+ // we remove data after header and try new attempt, if required
+ CMyComPtr<IInStream> fileSeekStream;
+ fileInStream->QueryInterface(IID_IInStream, (void **)&fileSeekStream);
+ if (!fileSeekStream)
+ return E_FAIL;
+ RINOK(fileSeekStream->Seek(0, STREAM_SEEK_SET, NULL));
+ RINOK(outSeekStream->SetSize(outArchive.Pos));
+ if (item.PackSize == 0)
+ break;
}
- RINOK(outArchive.FillDataResidual(item.PackSize));
}
}
complexity += item.PackSize;
+ fileInStream.Release();
RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
}
else
{
+ // (ui.NewData == false)
+
+ if (opCallback)
+ {
+ RINOK(opCallback->ReportOperation(
+ NEventIndexType::kInArcIndex, (UInt32)ui.IndexInArc,
+ NUpdateNotifyOp::kReplicate))
+ }
+
const CItemEx &existItem = inputItems[(unsigned)ui.IndexInArc];
- UInt64 size;
+ UInt64 size, pos;
if (ui.NewProps)
{
@@ -216,44 +511,37 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
item.PackSize = existItem.PackSize;
}
- item.DeviceMajorDefined = existItem.DeviceMajorDefined;
- item.DeviceMinorDefined = existItem.DeviceMinorDefined;
+ item.DeviceMajor_Defined = existItem.DeviceMajor_Defined;
+ item.DeviceMinor_Defined = existItem.DeviceMinor_Defined;
item.DeviceMajor = existItem.DeviceMajor;
item.DeviceMinor = existItem.DeviceMinor;
item.UID = existItem.UID;
item.GID = existItem.GID;
RINOK(outArchive.WriteHeader(item));
- RINOK(inStream->Seek((Int64)existItem.GetDataPosition(), STREAM_SEEK_SET, NULL));
- size = existItem.PackSize;
+ size = existItem.Get_PackSize_Aligned();
+ pos = existItem.Get_DataPos();
}
else
{
- RINOK(inStream->Seek((Int64)existItem.HeaderPos, STREAM_SEEK_SET, NULL));
- size = existItem.GetFullSize();
+ size = existItem.Get_FullSize_Aligned();
+ pos = existItem.HeaderPos;
}
-
- streamSpec->Init(size);
- if (opCallback)
+ if (size != 0)
{
- RINOK(opCallback->ReportOperation(
- NEventIndexType::kInArcIndex, (UInt32)ui.IndexInArc,
- NUpdateNotifyOp::kReplicate))
+ RINOK(inStream->Seek((Int64)pos, STREAM_SEEK_SET, NULL));
+ streamSpec->Init(size);
+ // 22.00 : we copy Residual data from old archive to new archive instead of zeroing
+ RINOK(copyCoder->Code(inStreamLimited, outStream, NULL, NULL, progress));
+ if (copyCoderSpec->TotalSize != size)
+ return E_FAIL;
+ outArchive.Pos += size;
+ // RINOK(outArchive.Write_AfterDataResidual(existItem.PackSize));
+ complexity += size;
}
-
- RINOK(copyCoder->Code(inStreamLimited, outStream, NULL, NULL, progress));
- if (copyCoderSpec->TotalSize != size)
- return E_FAIL;
- outArchive.Pos += size;
- RINOK(outArchive.FillDataResidual(existItem.PackSize));
- complexity += size;
}
}
-
- lps->InSize = lps->OutSize = complexity;
- RINOK(lps->SetCur());
- return outArchive.WriteFinishHeader();
}
}}
diff --git a/CPP/7zip/Archive/Tar/TarUpdate.h b/CPP/7zip/Archive/Tar/TarUpdate.h
index 1e3d0217..ca0976dd 100644..100755
--- a/CPP/7zip/Archive/Tar/TarUpdate.h
+++ b/CPP/7zip/Archive/Tar/TarUpdate.h
@@ -15,27 +15,60 @@ struct CUpdateItem
int IndexInArc;
unsigned IndexInClient;
UInt64 Size;
- Int64 MTime;
+ // Int64 MTime;
UInt32 Mode;
bool NewData;
bool NewProps;
bool IsDir;
+ bool DeviceMajor_Defined;
+ bool DeviceMinor_Defined;
+ UInt32 UID;
+ UInt32 GID;
+ UInt32 DeviceMajor;
+ UInt32 DeviceMinor;
AString Name;
AString User;
AString Group;
- CUpdateItem(): Size(0), IsDir(false) {}
+ CPaxTimes PaxTimes;
+
+ CUpdateItem():
+ Size(0),
+ IsDir(false),
+ DeviceMajor_Defined(false),
+ DeviceMinor_Defined(false),
+ UID(0),
+ GID(0)
+ {}
+};
+
+
+struct CUpdateOptions
+{
+ UINT CodePage;
+ unsigned UtfFlags;
+ bool PosixMode;
+ CBoolPair Write_MTime;
+ CBoolPair Write_ATime;
+ CBoolPair Write_CTime;
+ CTimeOptions TimeOptions;
};
+
HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
const CObjectVector<CItemEx> &inputItems,
const CObjectVector<CUpdateItem> &updateItems,
- UINT codePage, unsigned utfFlags,
+ const CUpdateOptions &options,
IArchiveUpdateCallback *updateCallback);
HRESULT GetPropString(IArchiveUpdateCallback *callback, UInt32 index, PROPID propId, AString &res,
UINT codePage, unsigned utfFlags, bool convertSlash);
+HRESULT Prop_To_PaxTime(const NWindows::NCOM::CPropVariant &prop, CPaxTime &pt);
+
+void Get_AString_From_UString(const UString &s, AString &res,
+ UINT codePage, unsigned utfFlags);
+
}}
#endif
diff --git a/CPP/7zip/Archive/Udf/StdAfx.h b/CPP/7zip/Archive/Udf/StdAfx.h
index 2854ff3e..2854ff3e 100644..100755
--- a/CPP/7zip/Archive/Udf/StdAfx.h
+++ b/CPP/7zip/Archive/Udf/StdAfx.h
diff --git a/CPP/7zip/Archive/Udf/UdfHandler.cpp b/CPP/7zip/Archive/Udf/UdfHandler.cpp
index 74ec0beb..2232c64a 100644..100755
--- a/CPP/7zip/Archive/Udf/UdfHandler.cpp
+++ b/CPP/7zip/Archive/Udf/UdfHandler.cpp
@@ -27,11 +27,17 @@ static void UdfTimeToFileTime(const CTime &t, NWindows::NCOM::CPropVariant &prop
return;
if (t.IsLocal())
numSecs -= (Int64)((Int32)t.GetMinutesOffset() * 60);
- FILETIME ft;
- UInt64 v = (((numSecs * 100 + d[9]) * 100 + d[10]) * 100 + d[11]) * 10;
- ft.dwLowDateTime = (UInt32)v;
- ft.dwHighDateTime = (UInt32)(v >> 32);
- prop = ft;
+ const UInt32 m0 = d[9];
+ const UInt32 m1 = d[10];
+ const UInt32 m2 = d[11];
+ unsigned numDigits = 0;
+ UInt64 v = numSecs * 10000000;
+ if (m0 < 100 && m1 < 100 && m2 < 100)
+ {
+ v += m0 * 100000 + m1 * 1000 + m2 * 10;
+ numDigits = 6;
+ }
+ prop.SetAsTimeFrom_Ft64_Prec(v, k_PropVar_TimePrec_Base + numDigits);
}
static const Byte kProps[] =
@@ -41,7 +47,8 @@ static const Byte kProps[] =
kpidSize,
kpidPackSize,
kpidMTime,
- kpidATime
+ kpidATime,
+ kpidChangeTime
};
static const Byte kArcProps[] =
@@ -205,6 +212,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidPackSize: if (!item.IsDir()) prop = (UInt64)item.NumLogBlockRecorded * vol.BlockSize; break;
case kpidMTime: UdfTimeToFileTime(item.MTime, prop); break;
case kpidATime: UdfTimeToFileTime(item.ATime, prop); break;
+ case kpidChangeTime: UdfTimeToFileTime(item.AttribTime, prop); break;
}
}
prop.Detach(value);
diff --git a/CPP/7zip/Archive/Udf/UdfHandler.h b/CPP/7zip/Archive/Udf/UdfHandler.h
index da44b232..da44b232 100644..100755
--- a/CPP/7zip/Archive/Udf/UdfHandler.h
+++ b/CPP/7zip/Archive/Udf/UdfHandler.h
diff --git a/CPP/7zip/Archive/Udf/UdfIn.cpp b/CPP/7zip/Archive/Udf/UdfIn.cpp
index 04d9228f..d2d2b20a 100644..100755
--- a/CPP/7zip/Archive/Udf/UdfIn.cpp
+++ b/CPP/7zip/Archive/Udf/UdfIn.cpp
@@ -333,7 +333,7 @@ void CItem::Parse(const Byte *p)
NumLogBlockRecorded = Get64(p + 64);
ATime.Parse(p + 72);
MTime.Parse(p + 84);
- // AttrtTime.Parse(p + 96);
+ AttribTime.Parse(p + 96);
// CheckPoint = Get32(p + 108);
// ExtendedAttrIcb.Parse(p + 112);
// ImplId.Parse(p + 128);
diff --git a/CPP/7zip/Archive/Udf/UdfIn.h b/CPP/7zip/Archive/Udf/UdfIn.h
index c26f6099..4e7dfa11 100644..100755
--- a/CPP/7zip/Archive/Udf/UdfIn.h
+++ b/CPP/7zip/Archive/Udf/UdfIn.h
@@ -243,7 +243,7 @@ struct CItem
UInt64 NumLogBlockRecorded;
CTime ATime;
CTime MTime;
- // CTime AttrtTime;
+ CTime AttribTime; // Attribute time : most recent date and time of the day of file creation or modification of the attributes of.
// UInt32 CheckPoint;
// CLongAllocDesc ExtendedAttrIcb;
// CRegId ImplId;
diff --git a/CPP/7zip/Archive/UefiHandler.cpp b/CPP/7zip/Archive/UefiHandler.cpp
index 67fe795a..67fe795a 100644..100755
--- a/CPP/7zip/Archive/UefiHandler.cpp
+++ b/CPP/7zip/Archive/UefiHandler.cpp
diff --git a/CPP/7zip/Archive/VdiHandler.cpp b/CPP/7zip/Archive/VdiHandler.cpp
index 7641cdc9..7641cdc9 100644..100755
--- a/CPP/7zip/Archive/VdiHandler.cpp
+++ b/CPP/7zip/Archive/VdiHandler.cpp
diff --git a/CPP/7zip/Archive/VhdHandler.cpp b/CPP/7zip/Archive/VhdHandler.cpp
index 8b9af45a..60bc3d30 100644..100755
--- a/CPP/7zip/Archive/VhdHandler.cpp
+++ b/CPP/7zip/Archive/VhdHandler.cpp
@@ -921,7 +921,8 @@ STDMETHODIMP CHandler::GetStream(UInt32 /* index */, ISequentialInStream **strea
CLimitedInStream *streamSpec = new CLimitedInStream;
CMyComPtr<ISequentialInStream> streamTemp = streamSpec;
streamSpec->SetStream(Stream);
- streamSpec->InitAndSeek(0, Footer.CurrentSize);
+ // fixme : check (startOffset = 0)
+ streamSpec->InitAndSeek(_startOffset, Footer.CurrentSize);
RINOK(streamSpec->SeekToStart());
*stream = streamTemp.Detach();
return S_OK;
diff --git a/CPP/7zip/Archive/VhdxHandler.cpp b/CPP/7zip/Archive/VhdxHandler.cpp
index e1e4692d..0fc83ace 100644..100755
--- a/CPP/7zip/Archive/VhdxHandler.cpp
+++ b/CPP/7zip/Archive/VhdxHandler.cpp
@@ -171,6 +171,20 @@ struct CHeader
UInt64 LogOffset;
CGuid Guids[3];
+ bool IsEqualTo(const CHeader &h) const
+ {
+ if (SequenceNumber != h.SequenceNumber)
+ return false;
+ if (LogLength != h.LogLength)
+ return false;
+ if (LogOffset != h.LogOffset)
+ return false;
+ for (unsigned i = 0; i < 3; i++)
+ if (!Guids[i].IsEqualTo(h.Guids[i]))
+ return false;
+ return true;
+ };
+
bool Parse(Byte *p);
};
@@ -1174,7 +1188,18 @@ HRESULT CHandler::Open3()
unsigned mainIndex;
if (headers[0].SequenceNumber > headers[1].SequenceNumber) mainIndex = 0;
else if (headers[0].SequenceNumber < headers[1].SequenceNumber) mainIndex = 1;
- else return S_FALSE;
+ else
+ {
+ /* Disk2vhd v2.02 can create image with 2 full copies of headers.
+ It's violation of VHDX specification:
+ "A header is current if it is the only valid header
+ or if it is valid and its SequenceNumber field is
+ greater than the other header's SequenceNumber".
+ but we support such Disk2vhd archives. */
+ if (!headers[0].IsEqualTo(headers[1]))
+ return S_FALSE;
+ mainIndex = 0;
+ }
const CHeader &h = headers[mainIndex];
Header = h;
@@ -1567,6 +1592,7 @@ static void AddComment_BlockSize(UString &s, const char *name, unsigned logSize)
void CHandler::AddComment(UString &s) const
{
+ AddComment_UInt64(s, "VirtualDiskSize", Meta.VirtualDiskSize);
AddComment_UInt64(s, "PhysicalSize", _phySize);
if (!_errorMessage.IsEmpty())
diff --git a/CPP/7zip/Archive/VmdkHandler.cpp b/CPP/7zip/Archive/VmdkHandler.cpp
index fb5bb1f8..40f56131 100644..100755
--- a/CPP/7zip/Archive/VmdkHandler.cpp
+++ b/CPP/7zip/Archive/VmdkHandler.cpp
@@ -138,7 +138,7 @@ static bool Str_to_ValName(const AString &s, AString &name, AString &val)
int eq = s.Find('=');
if (eq < 0 || (qu >= 0 && eq > qu))
return false;
- name = s.Left(eq);
+ name.SetFrom(s.Ptr(), eq);
name.Trim();
val = s.Ptr(eq + 1);
val.Trim();
diff --git a/CPP/7zip/Archive/Wim/StdAfx.h b/CPP/7zip/Archive/Wim/StdAfx.h
index 2854ff3e..2854ff3e 100644..100755
--- a/CPP/7zip/Archive/Wim/StdAfx.h
+++ b/CPP/7zip/Archive/Wim/StdAfx.h
diff --git a/CPP/7zip/Archive/Wim/WimHandler.cpp b/CPP/7zip/Archive/Wim/WimHandler.cpp
index 9e39d028..3b394557 100644..100755
--- a/CPP/7zip/Archive/Wim/WimHandler.cpp
+++ b/CPP/7zip/Archive/Wim/WimHandler.cpp
@@ -355,6 +355,7 @@ static void GetFileTime(const Byte *p, NCOM::CPropVariant &prop)
prop.vt = VT_FILETIME;
prop.filetime.dwLowDateTime = Get32(p);
prop.filetime.dwHighDateTime = Get32(p + 4);
+ prop.Set_FtPrec(k_PropVar_TimePrec_100ns);
}
@@ -842,7 +843,7 @@ public:
int dotPos = name.ReverseFind_Dot();
if (dotPos < 0)
dotPos = name.Len();
- _before = name.Left(dotPos);
+ _before.SetFrom(name.Ptr(), dotPos);
_after = name.Ptr(dotPos);
}
diff --git a/CPP/7zip/Archive/Wim/WimHandler.h b/CPP/7zip/Archive/Wim/WimHandler.h
index 3ba88d2b..3ba88d2b 100644..100755
--- a/CPP/7zip/Archive/Wim/WimHandler.h
+++ b/CPP/7zip/Archive/Wim/WimHandler.h
diff --git a/CPP/7zip/Archive/Wim/WimHandlerOut.cpp b/CPP/7zip/Archive/Wim/WimHandlerOut.cpp
index 6b4497fe..5e8365a4 100644..100755
--- a/CPP/7zip/Archive/Wim/WimHandlerOut.cpp
+++ b/CPP/7zip/Archive/Wim/WimHandlerOut.cpp
@@ -32,8 +32,8 @@ static int AddUniqHash(const CStreamInfo *streams, CUIntVector &sorted, const By
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 Byte *hash2 = streams[index].Hash;
unsigned i;
@@ -124,9 +124,9 @@ static int AddToHardLinkList(const CObjectVector<CMetaItem> &metaItems, unsigned
unsigned left = 0, right = indexes.Size();
while (left != right)
{
- unsigned mid = (left + right) / 2;
- unsigned index = indexes[mid];
- int comp = Compare_HardLink_MetaItems(mi, metaItems[index]);
+ const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2);
+ const unsigned index = indexes[mid];
+ const int comp = Compare_HardLink_MetaItems(mi, metaItems[index]);
if (comp == 0)
return index;
if (comp < 0)
@@ -203,8 +203,8 @@ bool CDir::FindDir(const CObjectVector<CMetaItem> &items, const UString &name, u
unsigned left = 0, right = Dirs.Size();
while (left != right)
{
- unsigned mid = (left + right) / 2;
- int comp = CompareFileNames(name, items[Dirs[mid].MetaIndex].Name);
+ const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2);
+ const int comp = CompareFileNames(name, items[Dirs[mid].MetaIndex].Name);
if (comp == 0)
{
index = mid;
diff --git a/CPP/7zip/Archive/Wim/WimIn.cpp b/CPP/7zip/Archive/Wim/WimIn.cpp
index fef6b34f..f805521a 100644..100755
--- a/CPP/7zip/Archive/Wim/WimIn.cpp
+++ b/CPP/7zip/Archive/Wim/WimIn.cpp
@@ -567,9 +567,12 @@ void CDatabase::GetItemPath(unsigned index1, bool showImageNumber, NWindows::NCO
for (unsigned i = 0; i < len; i++)
{
wchar_t c = Get16(meta + i * 2);
- // 18.06
- if (c == CHAR_PATH_SEPARATOR || c == '/')
- c = '_';
+ if (c == L'/')
+ c = L'_';
+ #if WCHAR_PATH_SEPARATOR != L'/'
+ else if (c == L'\\')
+ c = WCHAR_IN_FILE_NAME_BACKSLASH_REPLACEMENT; // 22.00 : WSL scheme
+ #endif
dest[i] = c;
}
}
diff --git a/CPP/7zip/Archive/Wim/WimIn.h b/CPP/7zip/Archive/Wim/WimIn.h
index 9e835b01..9e835b01 100644..100755
--- a/CPP/7zip/Archive/Wim/WimIn.h
+++ b/CPP/7zip/Archive/Wim/WimIn.h
diff --git a/CPP/7zip/Archive/Wim/WimRegister.cpp b/CPP/7zip/Archive/Wim/WimRegister.cpp
index ecebe8d9..e143f91c 100644..100755
--- a/CPP/7zip/Archive/Wim/WimRegister.cpp
+++ b/CPP/7zip/Archive/Wim/WimRegister.cpp
@@ -10,13 +10,20 @@ namespace NArchive {
namespace NWim {
REGISTER_ARC_IO(
- "wim", "wim swm esd ppkg", 0, 0xE6,
- kSignature,
- 0,
- NArcInfoFlags::kAltStreams |
- NArcInfoFlags::kNtSecure |
- NArcInfoFlags::kSymLinks |
- NArcInfoFlags::kHardLinks
+ "wim", "wim swm esd ppkg", NULL, 0xE6
+ , kSignature, 0
+ , NArcInfoFlags::kAltStreams
+ | NArcInfoFlags::kNtSecure
+ | NArcInfoFlags::kSymLinks
+ | NArcInfoFlags::kHardLinks
+ | NArcInfoFlags::kCTime
+ // | NArcInfoFlags::kCTime_Default
+ | NArcInfoFlags::kATime
+ // | NArcInfoFlags::kATime_Default
+ | 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/CPP/7zip/Archive/XarHandler.cpp b/CPP/7zip/Archive/XarHandler.cpp
index b5a1972d..b5a1972d 100644..100755
--- a/CPP/7zip/Archive/XarHandler.cpp
+++ b/CPP/7zip/Archive/XarHandler.cpp
diff --git a/CPP/7zip/Archive/XzHandler.cpp b/CPP/7zip/Archive/XzHandler.cpp
index f1afab66..d358ca56 100644..100755
--- a/CPP/7zip/Archive/XzHandler.cpp
+++ b/CPP/7zip/Archive/XzHandler.cpp
@@ -1089,7 +1089,8 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
STDMETHODIMP CHandler::GetFileTimeType(UInt32 *timeType)
{
- *timeType = NFileTimeType::kUnix;
+ *timeType = GET_FileTimeType_NotDefined_for_GetFileTimeType;
+ // *timeType = NFileTimeType::kUnix;
return S_OK;
}
@@ -1136,7 +1137,6 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (prop.vt != VT_UI8)
return E_INVALIDARG;
dataSize = prop.uhVal.QuadPart;
- RINOK(updateCallback->SetTotal(dataSize));
}
NCompress::NXz::CEncoder *encoderSpec = new NCompress::NXz::CEncoder;
@@ -1266,15 +1266,28 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
}
}
- CMyComPtr<ISequentialInStream> fileInStream;
- RINOK(updateCallback->GetStream(0, &fileInStream));
-
- CLocalProgress *lps = new CLocalProgress;
- CMyComPtr<ICompressProgressInfo> progress = lps;
- lps->Init(updateCallback, true);
-
- RINOK(encoderSpec->Code(fileInStream, outStream, NULL, NULL, progress));
-
+ {
+ 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(encoderSpec->Code(fileInStream, outStream, NULL, NULL, progress));
+ }
+
return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK);
}
@@ -1415,9 +1428,9 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
REGISTER_ARC_IO(
"xz", "xz txz", "* .tar", 0xC,
- XZ_SIG,
- 0,
- NArcInfoFlags::kKeepName,
- NULL)
+ XZ_SIG, 0
+ , NArcInfoFlags::kKeepName
+ , 0
+ , NULL)
}}
diff --git a/CPP/7zip/Archive/XzHandler.h b/CPP/7zip/Archive/XzHandler.h
index 24e8eeb4..24e8eeb4 100644..100755
--- a/CPP/7zip/Archive/XzHandler.h
+++ b/CPP/7zip/Archive/XzHandler.h
diff --git a/CPP/7zip/Archive/ZHandler.cpp b/CPP/7zip/Archive/ZHandler.cpp
index 29934367..29934367 100644..100755
--- a/CPP/7zip/Archive/ZHandler.cpp
+++ b/CPP/7zip/Archive/ZHandler.cpp
diff --git a/CPP/7zip/Archive/Zip/StdAfx.h b/CPP/7zip/Archive/Zip/StdAfx.h
index 2854ff3e..2854ff3e 100644..100755
--- a/CPP/7zip/Archive/Zip/StdAfx.h
+++ b/CPP/7zip/Archive/Zip/StdAfx.h
diff --git a/CPP/7zip/Archive/Zip/ZipAddCommon.cpp b/CPP/7zip/Archive/Zip/ZipAddCommon.cpp
index 2bb57d5c..2bb57d5c 100644..100755
--- a/CPP/7zip/Archive/Zip/ZipAddCommon.cpp
+++ b/CPP/7zip/Archive/Zip/ZipAddCommon.cpp
diff --git a/CPP/7zip/Archive/Zip/ZipAddCommon.h b/CPP/7zip/Archive/Zip/ZipAddCommon.h
index 0aa44adf..0aa44adf 100644..100755
--- a/CPP/7zip/Archive/Zip/ZipAddCommon.h
+++ b/CPP/7zip/Archive/Zip/ZipAddCommon.h
diff --git a/CPP/7zip/Archive/Zip/ZipCompressionMode.h b/CPP/7zip/Archive/Zip/ZipCompressionMode.h
index 842991c4..842991c4 100644..100755
--- a/CPP/7zip/Archive/Zip/ZipCompressionMode.h
+++ b/CPP/7zip/Archive/Zip/ZipCompressionMode.h
diff --git a/CPP/7zip/Archive/Zip/ZipHandler.cpp b/CPP/7zip/Archive/Zip/ZipHandler.cpp
index d8168bbe..1b3985fd 100644..100755
--- a/CPP/7zip/Archive/Zip/ZipHandler.cpp
+++ b/CPP/7zip/Archive/Zip/ZipHandler.cpp
@@ -190,6 +190,8 @@ static const Byte kProps[] =
kpidVolumeIndex,
kpidOffset
// kpidIsAltStream
+ // , kpidChangeTime // for debug
+ // , 255 // for debug
};
static const Byte kArcProps[] =
@@ -347,6 +349,34 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
return S_OK;
}
+
+static bool NtfsUnixTimeToProp(bool fromCentral,
+ const CExtraBlock &extra,
+ unsigned ntfsIndex, unsigned unixIndex, NWindows::NCOM::CPropVariant &prop)
+{
+ {
+ FILETIME ft;
+ if (extra.GetNtfsTime(ntfsIndex, ft))
+ {
+ PropVariant_SetFrom_NtfsTime(prop, ft);
+ return true;
+ }
+ }
+ {
+ UInt32 unixTime = 0;
+ if (!extra.GetUnixTime(fromCentral, unixIndex, unixTime))
+ return false;
+ /*
+ // we allow unixTime == 0
+ if (unixTime == 0)
+ return false;
+ */
+ PropVariant_SetFrom_UnixTime(prop, unixTime);
+ return true;
+ }
+}
+
+
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
@@ -392,6 +422,30 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidPackSize: prop = item.PackSize; break;
+ case kpidCTime:
+ NtfsUnixTimeToProp(item.FromCentral, extra,
+ NFileHeader::NNtfsExtra::kCTime,
+ NFileHeader::NUnixTime::kCTime, prop);
+ break;
+
+ case kpidATime:
+ NtfsUnixTimeToProp(item.FromCentral, extra,
+ NFileHeader::NNtfsExtra::kATime,
+ NFileHeader::NUnixTime::kATime, prop);
+ break;
+
+ case kpidMTime:
+ {
+ if (!NtfsUnixTimeToProp(item.FromCentral, extra,
+ NFileHeader::NNtfsExtra::kMTime,
+ NFileHeader::NUnixTime::kMTime, prop))
+ {
+ if (item.Time != 0)
+ PropVariant_SetFrom_DosTime(prop, item.Time);
+ }
+ break;
+ }
+
case kpidTimeType:
{
FILETIME ft;
@@ -399,7 +453,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
UInt32 type;
if (extra.GetNtfsTime(NFileHeader::NNtfsExtra::kMTime, ft))
type = NFileTimeType::kWindows;
- else if (extra.GetUnixTime(true, NFileHeader::NUnixTime::kMTime, unixTime))
+ else if (extra.GetUnixTime(item.FromCentral, NFileHeader::NUnixTime::kMTime, unixTime))
type = NFileTimeType::kUnix;
else
type = NFileTimeType::kDOS;
@@ -407,64 +461,28 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
break;
}
- case kpidCTime:
- {
- FILETIME utc;
- bool defined = true;
- if (!extra.GetNtfsTime(NFileHeader::NNtfsExtra::kCTime, utc))
- {
- UInt32 unixTime = 0;
- if (extra.GetUnixTime(true, NFileHeader::NUnixTime::kCTime, unixTime))
- NTime::UnixTimeToFileTime(unixTime, utc);
- else
- defined = false;
- }
- if (defined)
- prop = utc;
- break;
- }
-
- case kpidATime:
- {
- FILETIME utc;
- bool defined = true;
- if (!extra.GetNtfsTime(NFileHeader::NNtfsExtra::kATime, utc))
- {
- UInt32 unixTime = 0;
- if (extra.GetUnixTime(true, NFileHeader::NUnixTime::kATime, unixTime))
- NTime::UnixTimeToFileTime(unixTime, utc);
- else
- defined = false;
- }
- if (defined)
- prop = utc;
-
- break;
- }
-
- case kpidMTime:
+ /*
+ // for debug to get Dos time values:
+ case kpidChangeTime: if (item.Time != 0) PropVariant_SetFrom_DosTime(prop, item.Time); break;
+ // for debug
+ // time difference (dos - utc)
+ case 255:
{
- FILETIME utc;
- bool defined = true;
- if (!extra.GetNtfsTime(NFileHeader::NNtfsExtra::kMTime, utc))
+ if (NtfsUnixTimeToProp(item.FromCentral, extra,
+ NFileHeader::NNtfsExtra::kMTime,
+ NFileHeader::NUnixTime::kMTime, prop))
{
- UInt32 unixTime = 0;
- if (extra.GetUnixTime(true, NFileHeader::NUnixTime::kMTime, unixTime))
- NTime::UnixTimeToFileTime(unixTime, utc);
- else
+ FILETIME localFileTime;
+ if (item.Time != 0 && NTime::DosTime_To_FileTime(item.Time, localFileTime))
{
- FILETIME localFileTime;
- if (item.Time == 0)
- defined = false;
- else if (!NTime::DosTimeToFileTime(item.Time, localFileTime) ||
- !LocalFileTimeToFileTime(&localFileTime, &utc))
- utc.dwHighDateTime = utc.dwLowDateTime = 0;
+ UInt64 t1 = FILETIME_To_UInt64(prop.filetime);
+ UInt64 t2 = FILETIME_To_UInt64(localFileTime);
+ prop.Set_Int64(t2 - t1);
}
}
- if (defined)
- prop = utc;
break;
}
+ */
case kpidAttrib: prop = item.GetWinAttrib(); break;
@@ -1122,7 +1140,18 @@ HRESULT CZipDecoder::Decode(
AString_Wipe charPassword;
if (password)
{
- UnicodeStringToMultiByte2(charPassword, (LPCOLESTR)password, CP_ACP);
+ /*
+ // 22.00: do we need UTF-8 passwords here ?
+ if (item.IsUtf8()) // 22.00
+ {
+ // throw 1;
+ ConvertUnicodeToUTF8((LPCOLESTR)password, charPassword);
+ }
+ else
+ */
+ {
+ UnicodeStringToMultiByte2(charPassword, (LPCOLESTR)password, CP_ACP);
+ }
/*
if (wzAesMode || pkAesMode)
{
@@ -1341,6 +1370,8 @@ HRESULT CZipDecoder::Decode(
if (id == NFileHeader::NCompressionMethod::kStore && item.IsEncrypted())
{
+ // for debug : we can disable this code (kStore + 50), if we want to test CopyCoder+Filter
+ // here we use filter without CopyCoder
readFromFilter = false;
COutStreamWithPadPKCS7 *padStreamSpec = NULL;
@@ -1425,33 +1456,44 @@ HRESULT CZipDecoder::Decode(
const UInt32 padSize = _pkAesDecoderSpec->GetPadSize((UInt32)processed);
if (processed + padSize > coderPackSize)
truncatedError = true;
+ else if (processed + padSize < coderPackSize)
+ dataAfterEnd = true;
else
{
- if (processed + padSize < coderPackSize)
- dataAfterEnd = true;
- else
{
- // here we can PKCS7 padding data from reminder (it can be inside stream buffer in coder).
+ // here we check PKCS7 padding data from reminder (it can be inside stream buffer in coder).
CMyComPtr<ICompressReadUnusedFromInBuf> readInStream;
coder->QueryInterface(IID_ICompressReadUnusedFromInBuf, (void **)&readInStream);
- if (readInStream)
+ // CCopyCoder() for kStore doesn't read data outside of (item.Size)
+ if (readInStream || id == NFileHeader::NCompressionMethod::kStore)
{
- // change pad size, it we support another block size in ZipStron
- // here we request more to detect error with data after end.
+ // change pad size, if we support another block size in ZipStrong.
+ // here we request more data to detect error with data after end.
const UInt32 kBufSize = NCrypto::NZipStrong::kAesPadAllign + 16;
Byte buf[kBufSize];
- UInt32 processedSize;
- RINOK(readInStream->ReadUnusedFromInBuf(buf, kBufSize, &processedSize));
+ UInt32 processedSize = 0;
+ if (readInStream)
+ {
+ RINOK(readInStream->ReadUnusedFromInBuf(buf, kBufSize, &processedSize));
+ }
if (processedSize > padSize)
dataAfterEnd = true;
else
{
- if (ReadStream_FALSE(filterStream, buf + processedSize, padSize - processedSize) != S_OK)
- padError = true;
- else
- for (unsigned i = 0; i < padSize; i++)
- if (buf[i] != padSize)
- padError = true;
+ size_t processedSize2 = kBufSize - processedSize;
+ result = ReadStream(filterStream, buf + processedSize, &processedSize2);
+ if (result == S_OK)
+ {
+ processedSize2 += processedSize;
+ if (processedSize2 > padSize)
+ dataAfterEnd = true;
+ else if (processedSize2 < padSize)
+ truncatedError = true;
+ else
+ for (unsigned i = 0; i < padSize; i++)
+ if (buf[i] != padSize)
+ padError = true;
+ }
}
}
}
diff --git a/CPP/7zip/Archive/Zip/ZipHandler.h b/CPP/7zip/Archive/Zip/ZipHandler.h
index 3043e41c..a70a1a76 100644..100755
--- a/CPP/7zip/Archive/Zip/ZipHandler.h
+++ b/CPP/7zip/Archive/Zip/ZipHandler.h
@@ -57,7 +57,9 @@ private:
int m_MainMethod;
bool m_ForceAesMode;
- bool m_WriteNtfsTimeExtra;
+
+ CHandlerTimeOptions TimeOptions;
+
bool _removeSfxBlock;
bool m_ForceLocal;
bool m_ForceUtf8;
@@ -71,7 +73,8 @@ private:
_props.Init();
m_MainMethod = -1;
m_ForceAesMode = false;
- m_WriteNtfsTimeExtra = true;
+ TimeOptions.Init();
+ TimeOptions.Prec = k_PropVar_TimePrec_0;
_removeSfxBlock = false;
m_ForceLocal = false;
m_ForceUtf8 = false;
diff --git a/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp b/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp
index a9b3eae5..77a71df2 100644..100755
--- a/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp
+++ b/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp
@@ -30,7 +30,7 @@ namespace NZip {
STDMETHODIMP CHandler::GetFileTimeType(UInt32 *timeType)
{
- *timeType = NFileTimeType::kDOS;
+ *timeType = TimeOptions.Prec;
return S_OK;
}
@@ -207,27 +207,58 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
}
*/
+ // 22.00 : kpidTimeType is useless here : the code was disabled
+ /*
{
CPropVariant prop;
RINOK(callback->GetProperty(i, kpidTimeType, &prop));
if (prop.vt == VT_UI4)
- ui.NtfsTimeIsDefined = (prop.ulVal == NFileTimeType::kWindows);
+ ui.NtfsTime_IsDefined = (prop.ulVal == NFileTimeType::kWindows);
else
- ui.NtfsTimeIsDefined = m_WriteNtfsTimeExtra;
+ ui.NtfsTime_IsDefined = _Write_NtfsTime;
}
- RINOK(GetTime(callback, i, kpidMTime, ui.Ntfs_MTime));
- RINOK(GetTime(callback, i, kpidATime, ui.Ntfs_ATime));
- RINOK(GetTime(callback, i, kpidCTime, ui.Ntfs_CTime));
+ */
+
+ if (TimeOptions.Write_MTime.Val) RINOK (GetTime (callback, i, kpidMTime, ui.Ntfs_MTime));
+ if (TimeOptions.Write_ATime.Val) RINOK (GetTime (callback, i, kpidATime, ui.Ntfs_ATime));
+ if (TimeOptions.Write_CTime.Val) RINOK (GetTime (callback, i, kpidCTime, ui.Ntfs_CTime));
+ if (TimeOptions.Prec != k_PropVar_TimePrec_DOS)
{
- FILETIME localFileTime = { 0, 0 };
- if (ui.Ntfs_MTime.dwHighDateTime != 0 ||
- ui.Ntfs_MTime.dwLowDateTime != 0)
- if (!FileTimeToLocalFileTime(&ui.Ntfs_MTime, &localFileTime))
- return E_INVALIDARG;
- FileTimeToDosTime(localFileTime, ui.Time);
+ if (TimeOptions.Prec == k_PropVar_TimePrec_Unix ||
+ TimeOptions.Prec == k_PropVar_TimePrec_Base)
+ ui.Write_UnixTime = ! FILETIME_IsZero (ui.Ntfs_MTime);
+ else
+ {
+ /*
+ // if we want to store zero timestamps as zero timestamp, use the following:
+ ui.Write_NtfsTime =
+ _Write_MTime ||
+ _Write_ATime ||
+ _Write_CTime;
+ */
+
+ // We treat zero timestamp as no timestamp
+ ui.Write_NtfsTime =
+ ! FILETIME_IsZero (ui.Ntfs_MTime) ||
+ ! FILETIME_IsZero (ui.Ntfs_ATime) ||
+ ! FILETIME_IsZero (ui.Ntfs_CTime);
+ }
}
+ /*
+ how 0 in dos time works:
+ win10 explorer extract : some random date 1601-04-25.
+ winrar 6.10 : write time.
+ 7zip : MTime of archive is used
+ how 0 in tar works:
+ winrar 6.10 : 1970
+ 0 in dos field can show that there is no timestamp.
+ we write correct 1970-01-01 in dos field, to support correct extraction in Win10.
+ */
+
+ UtcFileTime_To_LocalDosTime(ui.Ntfs_MTime, ui.Time);
+
NItemName::ReplaceSlashes_OsToUnix(name);
bool needSlash = ui.IsDir;
@@ -441,11 +472,21 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (mainMethod != NFileHeader::NCompressionMethod::kStore)
options.MethodSequence.Add(NFileHeader::NCompressionMethod::kStore);
+ CUpdateOptions uo;
+ uo.Write_MTime = TimeOptions.Write_MTime.Val;
+ uo.Write_ATime = TimeOptions.Write_ATime.Val;
+ uo.Write_CTime = TimeOptions.Write_CTime.Val;
+ /*
+ uo.Write_NtfsTime = _Write_NtfsTime &&
+ (_Write_MTime || _Write_ATime || _Write_CTime);
+ uo.Write_UnixTime = _Write_UnixTime;
+ */
+
return Update(
EXTERNAL_CODECS_VARS
m_Items, updateItems, outStream,
m_Archive.IsOpen() ? &m_Archive : NULL, _removeSfxBlock,
- options, callback);
+ uo, options, callback);
COM_TRY_END2
}
@@ -494,10 +535,9 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
return E_INVALIDARG;
}
}
- else if (name.IsEqualTo("tc"))
- {
- RINOK(PROPVARIANT_to_bool(prop, m_WriteNtfsTimeExtra));
- }
+
+
+
else if (name.IsEqualTo("cl"))
{
RINOK(PROPVARIANT_to_bool(prop, m_ForceLocal));
@@ -532,7 +572,12 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
}
else
{
- RINOK(_props.SetProperty(name, prop));
+ bool processed = false;
+ RINOK(TimeOptions.Parse(name, prop, processed));
+ if (!processed)
+ {
+ RINOK(_props.SetProperty(name, prop));
+ }
}
// RINOK(_props.MethodInfo.ParseParamsFromPROPVARIANT(name, prop));
}
diff --git a/CPP/7zip/Archive/Zip/ZipHeader.h b/CPP/7zip/Archive/Zip/ZipHeader.h
index c47659ac..34fa359b 100644..100755
--- a/CPP/7zip/Archive/Zip/ZipHeader.h
+++ b/CPP/7zip/Archive/Zip/ZipHeader.h
@@ -88,14 +88,15 @@ namespace NFileHeader
{
kZip64 = 0x01,
kNTFS = 0x0A,
+ kUnix0 = 0x0D, // Info-ZIP : (UNIX) PK
kStrongEncrypt = 0x17,
kIzNtSecurityDescriptor = 0x4453,
- kUnixTime = 0x5455,
- kUnixExtra = 0x5855,
+ kUnixTime = 0x5455, // "UT" (time) Info-ZIP
+ kUnix1 = 0x5855, // Info-ZIP
kIzUnicodeComment = 0x6375,
kIzUnicodeName = 0x7075,
- kUnix2Extra = 0x7855,
- kUnix3Extra = 0x7875,
+ kUnix2 = 0x7855, // Info-ZIP
+ kUnixN = 0x7875, // Info-ZIP
kWzAES = 0x9901,
kApkAlign = 0xD935
};
diff --git a/CPP/7zip/Archive/Zip/ZipIn.cpp b/CPP/7zip/Archive/Zip/ZipIn.cpp
index 076d6bb5..f2b69a9c 100644..100755
--- a/CPP/7zip/Archive/Zip/ZipIn.cpp
+++ b/CPP/7zip/Archive/Zip/ZipIn.cpp
@@ -1045,9 +1045,24 @@ bool CInArchive::ReadExtra(const CLocalItem &item, unsigned extraSize, CExtraBlo
if (cdItem)
{
- if (isOK && ZIP64_IS_32_MAX(cdItem->LocalHeaderPos))
- { if (size < 8) isOK = false; else { size -= 8; cdItem->LocalHeaderPos = ReadUInt64(); }}
-
+ if (isOK)
+ {
+ if (ZIP64_IS_32_MAX(cdItem->LocalHeaderPos))
+ { if (size < 8) isOK = false; else { size -= 8; cdItem->LocalHeaderPos = ReadUInt64(); }}
+ /*
+ else if (size == 8)
+ {
+ size -= 8;
+ const UInt64 v = ReadUInt64();
+ // soong_zip, an AOSP tool (written in the Go) writes incorrect value.
+ // we can ignore that minor error here
+ if (v != cdItem->LocalHeaderPos)
+ isOK = false; // ignore error
+ // isOK = false; // force error
+ }
+ */
+ }
+
if (isOK && ZIP64_IS_16_MAX(cdItem->Disk))
{ if (size < 4) isOK = false; else { size -= 4; cdItem->Disk = ReadUInt32(); }}
}
@@ -1926,7 +1941,7 @@ static int FindItem(const CObjectVector<CItemEx> &items, const CItemEx &item)
{
if (left >= right)
return -1;
- const unsigned index = (left + right) / 2;
+ const unsigned index = (unsigned)(((size_t)left + (size_t)right) / 2);
const CItemEx &item2 = items[index];
if (item.Disk < item2.Disk)
right = index;
diff --git a/CPP/7zip/Archive/Zip/ZipIn.h b/CPP/7zip/Archive/Zip/ZipIn.h
index 1498afed..1498afed 100644..100755
--- a/CPP/7zip/Archive/Zip/ZipIn.h
+++ b/CPP/7zip/Archive/Zip/ZipIn.h
diff --git a/CPP/7zip/Archive/Zip/ZipItem.cpp b/CPP/7zip/Archive/Zip/ZipItem.cpp
index be336485..cffbb78a 100644..100755
--- a/CPP/7zip/Archive/Zip/ZipItem.cpp
+++ b/CPP/7zip/Archive/Zip/ZipItem.cpp
@@ -30,11 +30,12 @@ static const CUInt32PCharPair g_ExtraTypes[] =
{
{ NExtraID::kZip64, "Zip64" },
{ NExtraID::kNTFS, "NTFS" },
+ { NExtraID::kUnix0, "UNIX" },
{ NExtraID::kStrongEncrypt, "StrongCrypto" },
{ NExtraID::kUnixTime, "UT" },
- { NExtraID::kUnixExtra, "UX" },
- { NExtraID::kUnix2Extra, "Ux" },
- { NExtraID::kUnix3Extra, "ux" },
+ { NExtraID::kUnix1, "UX" },
+ { NExtraID::kUnix2, "Ux" },
+ { NExtraID::kUnixN, "ux" },
{ NExtraID::kIzUnicodeComment, "uc" },
{ NExtraID::kIzUnicodeName, "up" },
{ NExtraID::kIzNtSecurityDescriptor, "SD" },
@@ -50,6 +51,23 @@ void CExtraSubBlock::PrintInfo(AString &s) const
if (pair.Value == ID)
{
s += pair.Name;
+ if (ID == NExtraID::kUnixTime)
+ {
+ if (Data.Size() >= 1)
+ {
+ s += ':';
+ const Byte flags = Data[0];
+ if (flags & 1) s += 'M';
+ if (flags & 2) s += 'A';
+ if (flags & 4) s += 'C';
+ const UInt32 size = (UInt32)(Data.Size()) - 1;
+ if (size % 4 == 0)
+ {
+ s += ':';
+ s.Add_UInt32(size / 4);
+ }
+ }
+ }
/*
if (ID == NExtraID::kApkAlign && Data.Size() >= 2)
{
@@ -133,14 +151,22 @@ bool CExtraSubBlock::ExtractNtfsTime(unsigned index, FILETIME &ft) const
return false;
}
-bool CExtraSubBlock::ExtractUnixTime(bool isCentral, unsigned index, UInt32 &res) const
+bool CExtraSubBlock::Extract_UnixTime(bool isCentral, unsigned index, UInt32 &res) const
{
+ /* Info-Zip :
+ The central-header extra field contains the modification
+ time only, or no timestamp at all.
+ Size of Data is used to flag its presence or absence
+ If "Flags" indicates that Modtime is present in the local header
+ field, it MUST be present in the central header field, too
+ */
+
res = 0;
UInt32 size = (UInt32)Data.Size();
if (ID != NExtraID::kUnixTime || size < 5)
return false;
const Byte *p = (const Byte *)Data;
- Byte flags = *p++;
+ const Byte flags = *p++;
size--;
if (isCentral)
{
@@ -168,18 +194,35 @@ bool CExtraSubBlock::ExtractUnixTime(bool isCentral, unsigned index, UInt32 &res
}
-bool CExtraSubBlock::ExtractUnixExtraTime(unsigned index, UInt32 &res) const
+// Info-ZIP's abandoned "Unix1 timestamps & owner ID info"
+
+bool CExtraSubBlock::Extract_Unix01_Time(unsigned index, UInt32 &res) const
{
res = 0;
- const size_t size = Data.Size();
- unsigned offset = index * 4;
- if (ID != NExtraID::kUnixExtra || size < offset + 4)
+ const unsigned offset = index * 4;
+ if (Data.Size() < offset + 4)
+ return false;
+ if (ID != NExtraID::kUnix0 &&
+ ID != NExtraID::kUnix1)
return false;
const Byte *p = (const Byte *)Data + offset;
res = GetUi32(p);
return true;
}
+/*
+// PKWARE's Unix "extra" is similar to Info-ZIP's abandoned "Unix1 timestamps"
+bool CExtraSubBlock::Extract_Unix_Time(unsigned index, UInt32 &res) const
+{
+ res = 0;
+ const unsigned offset = index * 4;
+ if (ID != NExtraID::kUnix0 || Data.Size() < offset)
+ return false;
+ const Byte *p = (const Byte *)Data + offset;
+ res = GetUi32(p);
+ return true;
+}
+*/
bool CExtraBlock::GetNtfsTime(unsigned index, FILETIME &ft) const
{
@@ -199,7 +242,7 @@ bool CExtraBlock::GetUnixTime(bool isCentral, unsigned index, UInt32 &res) const
{
const CExtraSubBlock &sb = SubBlocks[i];
if (sb.ID == NFileHeader::NExtraID::kUnixTime)
- return sb.ExtractUnixTime(isCentral, index, res);
+ return sb.Extract_UnixTime(isCentral, index, res);
}
}
@@ -214,8 +257,9 @@ bool CExtraBlock::GetUnixTime(bool isCentral, unsigned index, UInt32 &res) const
FOR_VECTOR (i, SubBlocks)
{
const CExtraSubBlock &sb = SubBlocks[i];
- if (sb.ID == NFileHeader::NExtraID::kUnixExtra)
- return sb.ExtractUnixExtraTime(index, res);
+ if (sb.ID == NFileHeader::NExtraID::kUnix0 ||
+ sb.ID == NFileHeader::NExtraID::kUnix1)
+ return sb.Extract_Unix01_Time(index, res);
}
}
return false;
diff --git a/CPP/7zip/Archive/Zip/ZipItem.h b/CPP/7zip/Archive/Zip/ZipItem.h
index 6ee87658..934d7ecf 100644..100755
--- a/CPP/7zip/Archive/Zip/ZipItem.h
+++ b/CPP/7zip/Archive/Zip/ZipItem.h
@@ -31,8 +31,9 @@ struct CExtraSubBlock
CByteBuffer Data;
bool ExtractNtfsTime(unsigned index, FILETIME &ft) const;
- bool ExtractUnixTime(bool isCentral, unsigned index, UInt32 &res) const;
- bool ExtractUnixExtraTime(unsigned index, UInt32 &res) const;
+ bool Extract_UnixTime(bool isCentral, unsigned index, UInt32 &res) const;
+ bool Extract_Unix01_Time(unsigned index, UInt32 &res) const;
+ // bool Extract_Unix_Time(unsigned index, UInt32 &res) const;
bool CheckIzUnicode(const AString &s) const;
diff --git a/CPP/7zip/Archive/Zip/ZipOut.cpp b/CPP/7zip/Archive/Zip/ZipOut.cpp
index efed0a41..8f3f43bf 100644..100755
--- a/CPP/7zip/Archive/Zip/ZipOut.cpp
+++ b/CPP/7zip/Archive/Zip/ZipOut.cpp
@@ -4,6 +4,7 @@
#include "../../../../C/7zCrc.h"
+#include "../../../Windows/TimeUtils.h"
#include "../../Common/OffsetStream.h"
#include "ZipOut.h"
@@ -110,6 +111,40 @@ void COutArchive::WriteUtfName(const CItemOut &item)
WriteBytes(item.Name_Utf, (UInt16)item.Name_Utf.Size());
}
+
+static const unsigned k_Ntfs_ExtraSize = 4 + 2 + 2 + (3 * 8);
+static const unsigned k_UnixTime_ExtraSize = 1 + (1 * 4);
+
+void COutArchive::WriteTimeExtra(const CItemOut &item, bool writeNtfs)
+{
+ if (writeNtfs)
+ {
+ // windows explorer ignores that extra
+ Write16(NFileHeader::NExtraID::kNTFS);
+ Write16(k_Ntfs_ExtraSize);
+ Write32(0); // reserved
+ Write16(NFileHeader::NNtfsExtra::kTagTime);
+ Write16(8 * 3);
+ WriteNtfsTime(item.Ntfs_MTime);
+ WriteNtfsTime(item.Ntfs_ATime);
+ WriteNtfsTime(item.Ntfs_CTime);
+ }
+
+ if (item.Write_UnixTime)
+ {
+ // windows explorer ignores that extra
+ // by specification : should we write to local header also?
+ Write16(NFileHeader::NExtraID::kUnixTime);
+ Write16(k_UnixTime_ExtraSize);
+ const Byte flags = (Byte)((unsigned)1 << NFileHeader::NUnixTime::kMTime);
+ Write8(flags);
+ UInt32 unixTime;
+ NWindows::NTime::FileTime_To_UnixTime(item.Ntfs_MTime, unixTime);
+ Write32(unixTime);
+ }
+}
+
+
void COutArchive::WriteLocalHeader(CItemOut &item, bool needCheck)
{
m_LocalHeaderPos = m_CurPos;
@@ -122,8 +157,14 @@ void COutArchive::WriteLocalHeader(CItemOut &item, bool needCheck)
if (needCheck && m_IsZip64)
isZip64 = true;
+ // Why don't we write NTFS timestamps to local header?
+ // Probably we want to reduce size of archive?
+ const bool writeNtfs = false; // do not write NTFS timestamp to local header
+ // const bool writeNtfs = item.Write_NtfsTime; // write NTFS time to local header
const UInt32 localExtraSize = (UInt32)(
(isZip64 ? (4 + 8 + 8): 0)
+ + (writeNtfs ? 4 + k_Ntfs_ExtraSize : 0)
+ + (item.Write_UnixTime ? 4 + k_UnixTime_ExtraSize : 0)
+ item.Get_UtfName_ExtraSize()
+ item.LocalExtra.GetSize());
if ((UInt16)localExtraSize != localExtraSize)
@@ -168,13 +209,12 @@ void COutArchive::WriteLocalHeader(CItemOut &item, bool needCheck)
Write64(packSize);
}
+ WriteTimeExtra(item, writeNtfs);
+
WriteUtfName(item);
WriteExtra(item.LocalExtra);
- // Why don't we write NTFS timestamps to local header?
- // Probably we want to reduce size of archive?
-
const UInt32 localFileHeaderSize = (UInt32)(m_CurPos - m_LocalHeaderPos);
if (needCheck && m_LocalFileHeaderSize != localFileHeaderSize)
throw CSystemException(E_FAIL);
@@ -231,10 +271,10 @@ void COutArchive::WriteDescriptor(const CItemOut &item)
void COutArchive::WriteCentralHeader(const CItemOut &item)
{
- bool isUnPack64 = DOES_NEED_ZIP64(item.Size);
- bool isPack64 = DOES_NEED_ZIP64(item.PackSize);
- bool isPosition64 = DOES_NEED_ZIP64(item.LocalHeaderPos);
- bool isZip64 = isPack64 || isUnPack64 || isPosition64;
+ const bool isUnPack64 = DOES_NEED_ZIP64(item.Size);
+ const bool isPack64 = DOES_NEED_ZIP64(item.PackSize);
+ const bool isPosition64 = DOES_NEED_ZIP64(item.LocalHeaderPos);
+ const bool isZip64 = isPack64 || isUnPack64 || isPosition64;
Write32(NSignature::kCentralFileHeader);
Write8(item.MadeByVersion.Version);
@@ -249,10 +289,11 @@ void COutArchive::WriteCentralHeader(const CItemOut &item)
Write16((UInt16)item.Name.Len());
const UInt16 zip64ExtraSize = (UInt16)((isUnPack64 ? 8: 0) + (isPack64 ? 8: 0) + (isPosition64 ? 8: 0));
- const UInt16 kNtfsExtraSize = 4 + 2 + 2 + (3 * 8);
+ const bool writeNtfs = item.Write_NtfsTime;
const size_t centralExtraSize =
(isZip64 ? 4 + zip64ExtraSize : 0)
- + (item.NtfsTimeIsDefined ? 4 + kNtfsExtraSize : 0)
+ + (writeNtfs ? 4 + k_Ntfs_ExtraSize : 0)
+ + (item.Write_UnixTime ? 4 + k_UnixTime_ExtraSize : 0)
+ item.Get_UtfName_ExtraSize()
+ item.CentralExtra.GetSize();
@@ -283,18 +324,7 @@ void COutArchive::WriteCentralHeader(const CItemOut &item)
Write64(item.LocalHeaderPos);
}
- if (item.NtfsTimeIsDefined)
- {
- Write16(NFileHeader::NExtraID::kNTFS);
- Write16(kNtfsExtraSize);
- Write32(0); // reserved
- Write16(NFileHeader::NNtfsExtra::kTagTime);
- Write16(8 * 3);
- WriteNtfsTime(item.Ntfs_MTime);
- WriteNtfsTime(item.Ntfs_ATime);
- WriteNtfsTime(item.Ntfs_CTime);
- }
-
+ WriteTimeExtra(item, writeNtfs);
WriteUtfName(item);
WriteExtra(item.CentralExtra);
@@ -304,15 +334,15 @@ void COutArchive::WriteCentralHeader(const CItemOut &item)
void COutArchive::WriteCentralDir(const CObjectVector<CItemOut> &items, const CByteBuffer *comment)
{
- UInt64 cdOffset = GetCurPos();
+ const UInt64 cdOffset = GetCurPos();
FOR_VECTOR (i, items)
WriteCentralHeader(items[i]);
- UInt64 cd64EndOffset = GetCurPos();
- UInt64 cdSize = cd64EndOffset - cdOffset;
- bool cdOffset64 = DOES_NEED_ZIP64(cdOffset);
- bool cdSize64 = DOES_NEED_ZIP64(cdSize);
- bool items64 = items.Size() >= 0xFFFF;
- bool isZip64 = (cdOffset64 || cdSize64 || items64);
+ const UInt64 cd64EndOffset = GetCurPos();
+ const UInt64 cdSize = cd64EndOffset - cdOffset;
+ const bool cdOffset64 = DOES_NEED_ZIP64(cdOffset);
+ const bool cdSize64 = DOES_NEED_ZIP64(cdSize);
+ const bool items64 = items.Size() >= 0xFFFF;
+ const bool isZip64 = (cdOffset64 || cdSize64 || items64);
// isZip64 = true; // to test Zip64
diff --git a/CPP/7zip/Archive/Zip/ZipOut.h b/CPP/7zip/Archive/Zip/ZipOut.h
index 3546411c..a645d67f 100644..100755
--- a/CPP/7zip/Archive/Zip/ZipOut.h
+++ b/CPP/7zip/Archive/Zip/ZipOut.h
@@ -18,7 +18,8 @@ public:
FILETIME Ntfs_MTime;
FILETIME Ntfs_ATime;
FILETIME Ntfs_CTime;
- bool NtfsTimeIsDefined;
+ bool Write_NtfsTime;
+ bool Write_UnixTime;
// It's possible that NtfsTime is not defined, but there is NtfsTime in Extra.
@@ -32,7 +33,10 @@ public:
return 4 + 5 + size;
}
- CItemOut(): NtfsTimeIsDefined(false) {}
+ CItemOut():
+ Write_NtfsTime(false),
+ Write_UnixTime(false)
+ {}
};
@@ -62,6 +66,7 @@ class COutArchive
Write32(ft.dwHighDateTime);
}
+ void WriteTimeExtra(const CItemOut &item, bool writeNtfs);
void WriteUtfName(const CItemOut &item);
void WriteExtra(const CExtraBlock &extra);
void WriteCommonItemInfo(const CLocalItem &item, bool isZip64);
diff --git a/CPP/7zip/Archive/Zip/ZipRegister.cpp b/CPP/7zip/Archive/Zip/ZipRegister.cpp
index e6929f1b..3ad47153 100644..100755
--- a/CPP/7zip/Archive/Zip/ZipRegister.cpp
+++ b/CPP/7zip/Archive/Zip/ZipRegister.cpp
@@ -20,9 +20,19 @@ REGISTER_ARC_IO(
"zip", "zip z01 zipx jar xpi odt ods docx xlsx epub ipa apk appx", 0, 1,
k_Signature,
0,
- NArcInfoFlags::kFindSignature |
- NArcInfoFlags::kMultiSignature |
- NArcInfoFlags::kUseGlobalOffset,
- IsArc_Zip)
+ NArcInfoFlags::kFindSignature
+ | NArcInfoFlags::kMultiSignature
+ | NArcInfoFlags::kUseGlobalOffset
+ | NArcInfoFlags::kCTime
+ // | NArcInfoFlags::kCTime_Default
+ | NArcInfoFlags::kATime
+ // | NArcInfoFlags::kATime_Default
+ | NArcInfoFlags::kMTime
+ | NArcInfoFlags::kMTime_Default
+ , TIME_PREC_TO_ARC_FLAGS_MASK (NFileTimeType::kWindows)
+ | TIME_PREC_TO_ARC_FLAGS_MASK (NFileTimeType::kUnix)
+ | TIME_PREC_TO_ARC_FLAGS_MASK (NFileTimeType::kDOS)
+ | TIME_PREC_TO_ARC_FLAGS_TIME_DEFAULT (NFileTimeType::kWindows)
+ , IsArc_Zip)
}}
diff --git a/CPP/7zip/Archive/Zip/ZipUpdate.cpp b/CPP/7zip/Archive/Zip/ZipUpdate.cpp
index 26636c78..7f13071a 100644..100755
--- a/CPP/7zip/Archive/Zip/ZipUpdate.cpp
+++ b/CPP/7zip/Archive/Zip/ZipUpdate.cpp
@@ -74,7 +74,9 @@ static void Copy_From_UpdateItem_To_ItemOut(const CUpdateItem &ui, CItemOut &ite
item.Ntfs_MTime = ui.Ntfs_MTime;
item.Ntfs_ATime = ui.Ntfs_ATime;
item.Ntfs_CTime = ui.Ntfs_CTime;
- item.NtfsTimeIsDefined = ui.NtfsTimeIsDefined;
+
+ item.Write_UnixTime = ui.Write_UnixTime;
+ item.Write_NtfsTime = ui.Write_NtfsTime;
}
static void SetFileHeader(
@@ -476,12 +478,9 @@ static void WriteDirHeader(COutArchive &archive, const CCompressionMethodMode *o
}
-static inline bool IsZero_FILETIME(const FILETIME &ft)
-{
- return (ft.dwHighDateTime == 0 && ft.dwLowDateTime == 0);
-}
-
-static void UpdatePropsFromStream(CUpdateItem &item, ISequentialInStream *fileInStream,
+static void UpdatePropsFromStream(
+ const CUpdateOptions &options,
+ CUpdateItem &item, ISequentialInStream *fileInStream,
IArchiveUpdateCallback *updateCallback, UInt64 &totalComplexity)
{
CMyComPtr<IStreamGetProps> getProps;
@@ -505,36 +504,100 @@ static void UpdatePropsFromStream(CUpdateItem &item, ISequentialInStream *fileIn
}
item.Size = size;
}
-
- if (!IsZero_FILETIME(mTime))
- {
- item.Ntfs_MTime = mTime;
- FILETIME loc = { 0, 0 };
- if (FileTimeToLocalFileTime(&mTime, &loc))
+
+ if (options.Write_MTime)
+ if (!FILETIME_IsZero(mTime))
{
- item.Time = 0;
- NTime::FileTimeToDosTime(loc, item.Time);
+ item.Ntfs_MTime = mTime;
+ NTime::UtcFileTime_To_LocalDosTime(mTime, item.Time);
}
- }
- if (!IsZero_FILETIME(cTime)) item.Ntfs_CTime = cTime;
- if (!IsZero_FILETIME(aTime)) item.Ntfs_ATime = aTime;
+ if (options.Write_CTime) if (!FILETIME_IsZero(cTime)) item.Ntfs_CTime = cTime;
+ if (options.Write_ATime) if (!FILETIME_IsZero(aTime)) item.Ntfs_ATime = aTime;
item.Attrib = attrib;
}
+/*
+static HRESULT ReportProps(
+ IArchiveUpdateCallbackArcProp *reportArcProp,
+ UInt32 index,
+ const CItemOut &item,
+ bool isAesMode)
+{
+ PROPVARIANT prop;
+ prop.vt = VT_EMPTY;
+ prop.wReserved1 = 0;
+
+ NCOM::PropVarEm_Set_UInt64(&prop, item.Size);
+ RINOK(reportArcProp->ReportProp(NEventIndexType::kOutArcIndex, index, kpidSize, &prop));
+
+ NCOM::PropVarEm_Set_UInt64(&prop, item.PackSize);
+ RINOK(reportArcProp->ReportProp(NEventIndexType::kOutArcIndex, index, kpidPackSize, &prop));
+
+ if (!isAesMode)
+ {
+ NCOM::PropVarEm_Set_UInt32(&prop, item.Crc);
+ RINOK(reportArcProp->ReportProp(NEventIndexType::kOutArcIndex, index, kpidCRC, &prop));
+ }
+
+ RINOK(reportArcProp->ReportFinished(NEventIndexType::kOutArcIndex, index, NUpdate::NOperationResult::kOK));
+
+ // if (opCallback) RINOK(opCallback->ReportOperation(NEventIndexType::kOutArcIndex, index, NUpdateNotifyOp::kOpFinished))
+
+ return S_OK;
+}
+*/
+
+/*
+struct CTotalStats
+{
+ UInt64 Size;
+ UInt64 PackSize;
+
+ void UpdateWithItem(const CItemOut &item)
+ {
+ Size += item.Size;
+ PackSize += item.PackSize;
+ }
+};
+
+static HRESULT ReportArcProps(IArchiveUpdateCallbackArcProp *reportArcProp,
+ CTotalStats &st)
+{
+ PROPVARIANT prop;
+ prop.vt = VT_EMPTY;
+ prop.wReserved1 = 0;
+ {
+ NWindows::NCOM::PropVarEm_Set_UInt64(&prop, st.Size);
+ RINOK(reportArcProp->ReportProp(
+ NEventIndexType::kArcProp, 0, kpidSize, &prop));
+ }
+ {
+ NWindows::NCOM::PropVarEm_Set_UInt64(&prop, st.PackSize);
+ RINOK(reportArcProp->ReportProp(
+ NEventIndexType::kArcProp, 0, kpidPackSize, &prop));
+ }
+ return S_OK;
+}
+*/
+
+
static HRESULT Update2St(
DECL_EXTERNAL_CODECS_LOC_VARS
COutArchive &archive,
CInArchive *inArchive,
const CObjectVector<CItemEx> &inputItems,
CObjectVector<CUpdateItem> &updateItems,
+ const CUpdateOptions &updateOptions,
const CCompressionMethodMode *options, bool outSeqMode,
const CByteBuffer *comment,
IArchiveUpdateCallback *updateCallback,
UInt64 &totalComplexity,
- IArchiveUpdateCallbackFile *opCallback)
+ IArchiveUpdateCallbackFile *opCallback
+ // , IArchiveUpdateCallbackArcProp *reportArcProp
+ )
{
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
@@ -575,7 +638,8 @@ static HRESULT Update2St(
}
else
{
- CMyComPtr<ISequentialInStream> fileInStream;
+ CMyComPtr<ISequentialInStream> fileInStream;
+ {
HRESULT res = updateCallback->GetStream(ui.IndexInClient, &fileInStream);
if (res == S_FALSE)
{
@@ -596,7 +660,7 @@ static HRESULT Update2St(
}
// seqMode = true; // to test seqMode
- UpdatePropsFromStream(ui, fileInStream, updateCallback, totalComplexity);
+ UpdatePropsFromStream(updateOptions, ui, fileInStream, updateCallback, totalComplexity);
CCompressingResult compressingResult;
@@ -629,10 +693,11 @@ static HRESULT Update2St(
SetItemInfoFromCompressingResult(compressingResult, options->IsRealAesMode(), options->AesKeyMode, item);
archive.WriteLocalHeader_Replace(item);
-
- RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
- unpackSizeTotal += item.Size;
- packSizeTotal += item.PackSize;
+ }
+ // if (reportArcProp) RINOK(ReportProps(reportArcProp, ui.IndexInClient, item, options->IsRealAesMode()))
+ RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
+ unpackSizeTotal += item.Size;
+ packSizeTotal += item.PackSize;
}
}
else
@@ -656,6 +721,14 @@ static HRESULT Update2St(
archive.WriteCentralDir(items, comment);
+ /*
+ CTotalStats stat;
+ stat.Size = unpackSizeTotal;
+ stat.PackSize = packSizeTotal;
+ if (reportArcProp)
+ RINOK(ReportArcProps(reportArcProp, stat))
+ */
+
lps->ProgressOffset += kCentralHeaderSize * updateItems.Size() + 1;
return lps->SetCur();
}
@@ -667,6 +740,7 @@ static HRESULT Update2(
CInArchive *inArchive,
const CObjectVector<CItemEx> &inputItems,
CObjectVector<CUpdateItem> &updateItems,
+ const CUpdateOptions &updateOptions,
const CCompressionMethodMode &options, bool outSeqMode,
const CByteBuffer *comment,
IArchiveUpdateCallback *updateCallback)
@@ -674,6 +748,11 @@ static HRESULT Update2(
CMyComPtr<IArchiveUpdateCallbackFile> opCallback;
updateCallback->QueryInterface(IID_IArchiveUpdateCallbackFile, (void **)&opCallback);
+ /*
+ CMyComPtr<IArchiveUpdateCallbackArcProp> reportArcProp;
+ updateCallback->QueryInterface(IID_IArchiveUpdateCallbackArcProp, (void **)&reportArcProp);
+ */
+
bool unknownComplexity = false;
UInt64 complexity = 0;
UInt64 numFilesToCompress = 0;
@@ -901,11 +980,23 @@ static HRESULT Update2(
return Update2St(
EXTERNAL_CODECS_LOC_VARS
archive, inArchive,
- inputItems, updateItems, &options2, outSeqMode, comment, updateCallback, totalComplexity, opCallback);
+ inputItems, updateItems,
+ updateOptions,
+ &options2, outSeqMode,
+ comment, updateCallback, totalComplexity,
+ opCallback
+ // , reportArcProp
+ );
#ifndef _7ZIP_ST
+ /*
+ CTotalStats stat;
+ stat.Size = 0;
+ stat.PackSize = 0;
+ */
+
CObjectVector<CItemOut> items;
CMtProgressMixer *mtProgressMixerSpec = new CMtProgressMixer;
@@ -1021,7 +1112,7 @@ static HRESULT Update2(
RINOK(res);
if (!fileInStream)
return E_INVALIDARG;
- UpdatePropsFromStream(ui, fileInStream, updateCallback, totalComplexity);
+ UpdatePropsFromStream(updateOptions, ui, fileInStream, updateCallback, totalComplexity);
RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
}
@@ -1122,6 +1213,13 @@ static HRESULT Update2(
memRef.WriteToStream(memManager.GetBlockSize(), outStream);
archive.MoveCurPos(item.PackSize);
memRef.FreeOpt(&memManager);
+ /*
+ if (reportArcProp)
+ {
+ stat.UpdateWithItem(item);
+ RINOK(ReportProps(reportArcProp, ui.IndexInClient, item, options.IsRealAesMode()));
+ }
+ */
}
else
{
@@ -1202,6 +1300,14 @@ static HRESULT Update2(
options.IsRealAesMode(), options.AesKeyMode, item);
archive.WriteLocalHeader_Replace(item);
+
+ /*
+ if (reportArcProp)
+ {
+ stat.UpdateWithItem(item);
+ RINOK(ReportProps(reportArcProp, ui.IndexInClient, item, options.IsRealAesMode()));
+ }
+ */
}
else
{
@@ -1230,7 +1336,14 @@ static HRESULT Update2(
RINOK(mtCompressProgressMixer.SetRatioInfo(0, NULL, NULL));
archive.WriteCentralDir(items, comment);
-
+
+ /*
+ if (reportArcProp)
+ {
+ RINOK(ReportArcProps(reportArcProp, stat));
+ }
+ */
+
complexity += kCentralHeaderSize * updateItems.Size() + 1;
mtProgressMixerSpec->Mixer2->SetProgressOffset(complexity);
return mtCompressProgressMixer.SetRatioInfo(0, NULL, NULL);
@@ -1472,6 +1585,7 @@ HRESULT Update(
CObjectVector<CUpdateItem> &updateItems,
ISequentialOutStream *seqOutStream,
CInArchive *inArchive, bool removeSfx,
+ const CUpdateOptions &updateOptions,
const CCompressionMethodMode &compressionMethodMode,
IArchiveUpdateCallback *updateCallback)
{
@@ -1529,6 +1643,7 @@ HRESULT Update(
EXTERNAL_CODECS_LOC_VARS
outArchive, inArchive,
inputItems, updateItems,
+ updateOptions,
compressionMethodMode, outSeqMode,
inArchive ? &inArchive->ArcInfo.Comment : NULL,
updateCallback);
diff --git a/CPP/7zip/Archive/Zip/ZipUpdate.h b/CPP/7zip/Archive/Zip/ZipUpdate.h
index 95e72a47..d1e35347 100644..100755
--- a/CPP/7zip/Archive/Zip/ZipUpdate.h
+++ b/CPP/7zip/Archive/Zip/ZipUpdate.h
@@ -30,7 +30,9 @@ struct CUpdateItem
bool NewData;
bool NewProps;
bool IsDir;
- bool NtfsTimeIsDefined;
+ bool Write_NtfsTime;
+ bool Write_UnixTime;
+ // bool Write_UnixTime_ATime;
bool IsUtf8;
// bool IsAltStream;
int IndexInArc;
@@ -50,30 +52,50 @@ struct CUpdateItem
void Clear()
{
IsDir = false;
- NtfsTimeIsDefined = false;
+
+ Write_NtfsTime = false;
+ Write_UnixTime = false;
+
IsUtf8 = false;
// IsAltStream = false;
+ Time = 0;
Size = 0;
Name.Empty();
Name_Utf.Free();
Comment.Free();
+
+ FILETIME_Clear(Ntfs_MTime);
+ FILETIME_Clear(Ntfs_ATime);
+ FILETIME_Clear(Ntfs_CTime);
}
CUpdateItem():
IsDir(false),
- NtfsTimeIsDefined(false),
+ Write_NtfsTime(false),
+ Write_UnixTime(false),
IsUtf8(false),
// IsAltStream(false),
+ Time(0),
Size(0)
{}
};
+
+struct CUpdateOptions
+{
+ bool Write_MTime;
+ bool Write_ATime;
+ bool Write_CTime;
+};
+
+
HRESULT Update(
DECL_EXTERNAL_CODECS_LOC_VARS
const CObjectVector<CItemEx> &inputItems,
CObjectVector<CUpdateItem> &updateItems,
ISequentialOutStream *seqOutStream,
CInArchive *inArchive, bool removeSfx,
+ const CUpdateOptions &updateOptions,
const CCompressionMethodMode &compressionMethodMode,
IArchiveUpdateCallback *updateCallback);
diff --git a/CPP/7zip/Archive/makefile b/CPP/7zip/Archive/makefile
index 7512ad56..7512ad56 100644..100755
--- a/CPP/7zip/Archive/makefile
+++ b/CPP/7zip/Archive/makefile
diff --git a/CPP/7zip/Asm.mak b/CPP/7zip/Asm.mak
index c4073e89..c4073e89 100644..100755
--- a/CPP/7zip/Asm.mak
+++ b/CPP/7zip/Asm.mak
diff --git a/CPP/7zip/Bundles/Alone/Alone.dsp b/CPP/7zip/Bundles/Alone/Alone.dsp
index 84d3cdf7..84d3cdf7 100644..100755
--- a/CPP/7zip/Bundles/Alone/Alone.dsp
+++ b/CPP/7zip/Bundles/Alone/Alone.dsp
diff --git a/CPP/7zip/Bundles/Alone/Alone.dsw b/CPP/7zip/Bundles/Alone/Alone.dsw
index 65eca43f..65eca43f 100644..100755
--- a/CPP/7zip/Bundles/Alone/Alone.dsw
+++ b/CPP/7zip/Bundles/Alone/Alone.dsw
diff --git a/CPP/7zip/Bundles/Alone/StdAfx.cpp b/CPP/7zip/Bundles/Alone/StdAfx.cpp
index d0feea85..d0feea85 100644..100755
--- a/CPP/7zip/Bundles/Alone/StdAfx.cpp
+++ b/CPP/7zip/Bundles/Alone/StdAfx.cpp
diff --git a/CPP/7zip/Bundles/Alone/StdAfx.h b/CPP/7zip/Bundles/Alone/StdAfx.h
index 2854ff3e..2854ff3e 100644..100755
--- a/CPP/7zip/Bundles/Alone/StdAfx.h
+++ b/CPP/7zip/Bundles/Alone/StdAfx.h
diff --git a/CPP/7zip/Bundles/Alone/afxres.h b/CPP/7zip/Bundles/Alone/afxres.h
index c2fadd4a..c2fadd4a 100644..100755
--- a/CPP/7zip/Bundles/Alone/afxres.h
+++ b/CPP/7zip/Bundles/Alone/afxres.h
diff --git a/CPP/7zip/Bundles/Alone/makefile b/CPP/7zip/Bundles/Alone/makefile
index cc4b29ed..cc4b29ed 100644..100755
--- a/CPP/7zip/Bundles/Alone/makefile
+++ b/CPP/7zip/Bundles/Alone/makefile
diff --git a/CPP/7zip/Bundles/Alone/makefile.gcc b/CPP/7zip/Bundles/Alone/makefile.gcc
index 38f8d593..38f8d593 100644..100755
--- a/CPP/7zip/Bundles/Alone/makefile.gcc
+++ b/CPP/7zip/Bundles/Alone/makefile.gcc
diff --git a/CPP/7zip/Bundles/Alone/resource.rc b/CPP/7zip/Bundles/Alone/resource.rc
index c85acaa9..c85acaa9 100644..100755
--- a/CPP/7zip/Bundles/Alone/resource.rc
+++ b/CPP/7zip/Bundles/Alone/resource.rc
diff --git a/CPP/7zip/Bundles/Alone2/StdAfx.cpp b/CPP/7zip/Bundles/Alone2/StdAfx.cpp
index d0feea85..d0feea85 100644..100755
--- a/CPP/7zip/Bundles/Alone2/StdAfx.cpp
+++ b/CPP/7zip/Bundles/Alone2/StdAfx.cpp
diff --git a/CPP/7zip/Bundles/Alone2/StdAfx.h b/CPP/7zip/Bundles/Alone2/StdAfx.h
index 2854ff3e..2854ff3e 100644..100755
--- a/CPP/7zip/Bundles/Alone2/StdAfx.h
+++ b/CPP/7zip/Bundles/Alone2/StdAfx.h
diff --git a/CPP/7zip/Bundles/Alone2/makefile b/CPP/7zip/Bundles/Alone2/makefile
index 56de5b2e..357e78ee 100644..100755
--- a/CPP/7zip/Bundles/Alone2/makefile
+++ b/CPP/7zip/Bundles/Alone2/makefile
@@ -18,7 +18,6 @@ WIN_OBJS = $(WIN_OBJS) \
$O\FileLink.obj \
$O\FileSystem.obj \
$O\MemoryLock.obj \
- $O\PropVariantConv.obj \
$O\Registry.obj \
$O\SystemInfo.obj \
diff --git a/CPP/7zip/Bundles/Alone2/makefile.gcc b/CPP/7zip/Bundles/Alone2/makefile.gcc
index 1e7e17f1..f8d31dba 100644..100755
--- a/CPP/7zip/Bundles/Alone2/makefile.gcc
+++ b/CPP/7zip/Bundles/Alone2/makefile.gcc
@@ -81,7 +81,6 @@ COMMON_OBJS_2 = \
WIN_OBJS_2 = \
$O/ErrorMsg.o \
$O/FileLink.o \
- $O/PropVariantConv.o \
$O/SystemInfo.o \
7ZIP_COMMON_OBJS_2 = \
diff --git a/CPP/7zip/Bundles/Alone2/resource.rc b/CPP/7zip/Bundles/Alone2/resource.rc
index af24c175..af24c175 100644..100755
--- a/CPP/7zip/Bundles/Alone2/resource.rc
+++ b/CPP/7zip/Bundles/Alone2/resource.rc
diff --git a/CPP/7zip/Bundles/Alone7z/Alone.dsp b/CPP/7zip/Bundles/Alone7z/Alone.dsp
index 217e6d68..217e6d68 100644..100755
--- a/CPP/7zip/Bundles/Alone7z/Alone.dsp
+++ b/CPP/7zip/Bundles/Alone7z/Alone.dsp
diff --git a/CPP/7zip/Bundles/Alone7z/Alone.dsw b/CPP/7zip/Bundles/Alone7z/Alone.dsw
index 65eca43f..65eca43f 100644..100755
--- a/CPP/7zip/Bundles/Alone7z/Alone.dsw
+++ b/CPP/7zip/Bundles/Alone7z/Alone.dsw
diff --git a/CPP/7zip/Bundles/Alone7z/StdAfx.cpp b/CPP/7zip/Bundles/Alone7z/StdAfx.cpp
index d0feea85..d0feea85 100644..100755
--- a/CPP/7zip/Bundles/Alone7z/StdAfx.cpp
+++ b/CPP/7zip/Bundles/Alone7z/StdAfx.cpp
diff --git a/CPP/7zip/Bundles/Alone7z/StdAfx.h b/CPP/7zip/Bundles/Alone7z/StdAfx.h
index 2854ff3e..2854ff3e 100644..100755
--- a/CPP/7zip/Bundles/Alone7z/StdAfx.h
+++ b/CPP/7zip/Bundles/Alone7z/StdAfx.h
diff --git a/CPP/7zip/Bundles/Alone7z/makefile b/CPP/7zip/Bundles/Alone7z/makefile
index f87684c7..f87684c7 100644..100755
--- a/CPP/7zip/Bundles/Alone7z/makefile
+++ b/CPP/7zip/Bundles/Alone7z/makefile
diff --git a/CPP/7zip/Bundles/Alone7z/makefile.gcc b/CPP/7zip/Bundles/Alone7z/makefile.gcc
index 8565452b..8565452b 100644..100755
--- a/CPP/7zip/Bundles/Alone7z/makefile.gcc
+++ b/CPP/7zip/Bundles/Alone7z/makefile.gcc
diff --git a/CPP/7zip/Bundles/Alone7z/resource.rc b/CPP/7zip/Bundles/Alone7z/resource.rc
index 59378500..59378500 100644..100755
--- a/CPP/7zip/Bundles/Alone7z/resource.rc
+++ b/CPP/7zip/Bundles/Alone7z/resource.rc
diff --git a/CPP/7zip/Bundles/Fm/FM.dsp b/CPP/7zip/Bundles/Fm/FM.dsp
index 54efba98..54efba98 100644..100755
--- a/CPP/7zip/Bundles/Fm/FM.dsp
+++ b/CPP/7zip/Bundles/Fm/FM.dsp
diff --git a/CPP/7zip/Bundles/Fm/FM.dsw b/CPP/7zip/Bundles/Fm/FM.dsw
index 1c955d95..1c955d95 100644..100755
--- a/CPP/7zip/Bundles/Fm/FM.dsw
+++ b/CPP/7zip/Bundles/Fm/FM.dsw
diff --git a/CPP/7zip/Bundles/Fm/StdAfx.cpp b/CPP/7zip/Bundles/Fm/StdAfx.cpp
index d0feea85..d0feea85 100644..100755
--- a/CPP/7zip/Bundles/Fm/StdAfx.cpp
+++ b/CPP/7zip/Bundles/Fm/StdAfx.cpp
diff --git a/CPP/7zip/Bundles/Fm/StdAfx.h b/CPP/7zip/Bundles/Fm/StdAfx.h
index 15fd136e..15fd136e 100644..100755
--- a/CPP/7zip/Bundles/Fm/StdAfx.h
+++ b/CPP/7zip/Bundles/Fm/StdAfx.h
diff --git a/CPP/7zip/Bundles/Fm/makefile b/CPP/7zip/Bundles/Fm/makefile
index 2c80ca1d..33813e82 100644..100755
--- a/CPP/7zip/Bundles/Fm/makefile
+++ b/CPP/7zip/Bundles/Fm/makefile
@@ -20,7 +20,6 @@ WIN_OBJS = $(WIN_OBJS) \
$O\MemoryLock.obj \
$O\Menu.obj \
$O\ProcessUtils.obj \
- $O\PropVariantConv.obj \
$O\Registry.obj \
$O\ResourceString.obj \
$O\SystemInfo.obj \
diff --git a/CPP/7zip/Bundles/Fm/resource.rc b/CPP/7zip/Bundles/Fm/resource.rc
index ffcff11a..ebc2f74b 100644..100755
--- a/CPP/7zip/Bundles/Fm/resource.rc
+++ b/CPP/7zip/Bundles/Fm/resource.rc
@@ -3,5 +3,5 @@
STRINGTABLE
BEGIN
- 100 "7z zip rar 001 cab iso xz txz lzma tar cpio bz2 bzip2 tbz2 tbz gz gzip tgz tpz z taz lzh lha rpm deb arj vhd vhdx wim swm esd fat ntfs dmg hfs xar squashfs"
+ 100 "7z zip rar 001 cab iso xz txz lzma tar cpio bz2 bzip2 tbz2 tbz gz gzip tgz tpz z taz lzh lha rpm deb arj vhd vhdx wim swm esd fat ntfs dmg hfs xar squashfs apfs"
END
diff --git a/CPP/7zip/Bundles/Format7z/StdAfx.cpp b/CPP/7zip/Bundles/Format7z/StdAfx.cpp
index d0feea85..d0feea85 100644..100755
--- a/CPP/7zip/Bundles/Format7z/StdAfx.cpp
+++ b/CPP/7zip/Bundles/Format7z/StdAfx.cpp
diff --git a/CPP/7zip/Bundles/Format7z/StdAfx.h b/CPP/7zip/Bundles/Format7z/StdAfx.h
index 2854ff3e..2854ff3e 100644..100755
--- a/CPP/7zip/Bundles/Format7z/StdAfx.h
+++ b/CPP/7zip/Bundles/Format7z/StdAfx.h
diff --git a/CPP/7zip/Bundles/Format7z/makefile b/CPP/7zip/Bundles/Format7z/makefile
index 7276f175..7276f175 100644..100755
--- a/CPP/7zip/Bundles/Format7z/makefile
+++ b/CPP/7zip/Bundles/Format7z/makefile
diff --git a/CPP/7zip/Bundles/Format7z/resource.rc b/CPP/7zip/Bundles/Format7z/resource.rc
index 2f2b42ae..2f2b42ae 100644..100755
--- a/CPP/7zip/Bundles/Format7z/resource.rc
+++ b/CPP/7zip/Bundles/Format7z/resource.rc
diff --git a/CPP/7zip/Bundles/Format7zExtract/StdAfx.cpp b/CPP/7zip/Bundles/Format7zExtract/StdAfx.cpp
index d0feea85..d0feea85 100644..100755
--- a/CPP/7zip/Bundles/Format7zExtract/StdAfx.cpp
+++ b/CPP/7zip/Bundles/Format7zExtract/StdAfx.cpp
diff --git a/CPP/7zip/Bundles/Format7zExtract/StdAfx.h b/CPP/7zip/Bundles/Format7zExtract/StdAfx.h
index 2854ff3e..2854ff3e 100644..100755
--- a/CPP/7zip/Bundles/Format7zExtract/StdAfx.h
+++ b/CPP/7zip/Bundles/Format7zExtract/StdAfx.h
diff --git a/CPP/7zip/Bundles/Format7zExtract/makefile b/CPP/7zip/Bundles/Format7zExtract/makefile
index 9b4831a9..9b4831a9 100644..100755
--- a/CPP/7zip/Bundles/Format7zExtract/makefile
+++ b/CPP/7zip/Bundles/Format7zExtract/makefile
diff --git a/CPP/7zip/Bundles/Format7zExtract/resource.rc b/CPP/7zip/Bundles/Format7zExtract/resource.rc
index 6a654615..6a654615 100644..100755
--- a/CPP/7zip/Bundles/Format7zExtract/resource.rc
+++ b/CPP/7zip/Bundles/Format7zExtract/resource.rc
diff --git a/CPP/7zip/Bundles/Format7zExtractR/StdAfx.cpp b/CPP/7zip/Bundles/Format7zExtractR/StdAfx.cpp
index d0feea85..d0feea85 100644..100755
--- a/CPP/7zip/Bundles/Format7zExtractR/StdAfx.cpp
+++ b/CPP/7zip/Bundles/Format7zExtractR/StdAfx.cpp
diff --git a/CPP/7zip/Bundles/Format7zExtractR/StdAfx.h b/CPP/7zip/Bundles/Format7zExtractR/StdAfx.h
index 2854ff3e..2854ff3e 100644..100755
--- a/CPP/7zip/Bundles/Format7zExtractR/StdAfx.h
+++ b/CPP/7zip/Bundles/Format7zExtractR/StdAfx.h
diff --git a/CPP/7zip/Bundles/Format7zExtractR/makefile b/CPP/7zip/Bundles/Format7zExtractR/makefile
index 756c8ae6..756c8ae6 100644..100755
--- a/CPP/7zip/Bundles/Format7zExtractR/makefile
+++ b/CPP/7zip/Bundles/Format7zExtractR/makefile
diff --git a/CPP/7zip/Bundles/Format7zExtractR/resource.rc b/CPP/7zip/Bundles/Format7zExtractR/resource.rc
index 149f58c4..149f58c4 100644..100755
--- a/CPP/7zip/Bundles/Format7zExtractR/resource.rc
+++ b/CPP/7zip/Bundles/Format7zExtractR/resource.rc
diff --git a/CPP/7zip/Bundles/Format7zF/Arc.mak b/CPP/7zip/Bundles/Format7zF/Arc.mak
index d8468a6f..209aea32 100644..100755
--- a/CPP/7zip/Bundles/Format7zF/Arc.mak
+++ b/CPP/7zip/Bundles/Format7zF/Arc.mak
@@ -24,6 +24,7 @@ WIN_OBJS = \
$O\FileIO.obj \
$O\FileName.obj \
$O\PropVariant.obj \
+ $O\PropVariantConv.obj \
$O\PropVariantUtils.obj \
$O\Synchronization.obj \
$O\System.obj \
@@ -53,6 +54,7 @@ WIN_OBJS = \
$O\VirtThread.obj \
AR_OBJS = \
+ $O\ApfsHandler.obj \
$O\ApmHandler.obj \
$O\ArHandler.obj \
$O\ArjHandler.obj \
@@ -72,6 +74,7 @@ AR_OBJS = \
$O\HandlerCont.obj \
$O\HfsHandler.obj \
$O\IhexHandler.obj \
+ $O\LpHandler.obj \
$O\LzhHandler.obj \
$O\LzmaHandler.obj \
$O\MachoHandler.obj \
@@ -83,6 +86,7 @@ AR_OBJS = \
$O\PpmdHandler.obj \
$O\QcowHandler.obj \
$O\RpmHandler.obj \
+ $O\SparseHandler.obj \
$O\SplitHandler.obj \
$O\SquashfsHandler.obj \
$O\SwfHandler.obj \
diff --git a/CPP/7zip/Bundles/Format7zF/Arc_gcc.mak b/CPP/7zip/Bundles/Format7zF/Arc_gcc.mak
index 8021f68a..e5e1e21b 100644..100755
--- a/CPP/7zip/Bundles/Format7zF/Arc_gcc.mak
+++ b/CPP/7zip/Bundles/Format7zF/Arc_gcc.mak
@@ -59,6 +59,7 @@ WIN_OBJS = \
$O/FileIO.o \
$O/FileName.o \
$O/PropVariant.o \
+ $O/PropVariantConv.o \
$O/PropVariantUtils.o \
$O/System.o \
$O/TimeUtils.o \
@@ -82,6 +83,7 @@ WIN_OBJS = \
$O/UniqBlocks.o \
AR_OBJS = \
+ $O/ApfsHandler.o \
$O/ApmHandler.o \
$O/ArHandler.o \
$O/ArjHandler.o \
@@ -101,6 +103,7 @@ AR_OBJS = \
$O/HandlerCont.o \
$O/HfsHandler.o \
$O/IhexHandler.o \
+ $O/LpHandler.o \
$O/LzhHandler.o \
$O/LzmaHandler.o \
$O/MachoHandler.o \
@@ -112,6 +115,7 @@ AR_OBJS = \
$O/PpmdHandler.o \
$O/QcowHandler.o \
$O/RpmHandler.o \
+ $O/SparseHandler.o \
$O/SplitHandler.o \
$O/SquashfsHandler.o \
$O/SwfHandler.o \
diff --git a/CPP/7zip/Bundles/Format7zF/Format7z.dsp b/CPP/7zip/Bundles/Format7zF/Format7z.dsp
index 6b55e93d..cf2d9e86 100644..100755
--- a/CPP/7zip/Bundles/Format7zF/Format7z.dsp
+++ b/CPP/7zip/Bundles/Format7zF/Format7z.dsp
@@ -2763,6 +2763,10 @@ SOURCE=..\..\Archive\Udf\UdfIn.h
# End Group
# Begin Source File
+SOURCE=..\..\Archive\ApfsHandler.cpp
+# End Source File
+# Begin Source File
+
SOURCE=..\..\Archive\ApmHandler.cpp
# End Source File
# Begin Source File
@@ -2851,6 +2855,10 @@ SOURCE=..\..\Archive\IhexHandler.cpp
# End Source File
# Begin Source File
+SOURCE=..\..\Archive\LpHandler.cpp
+# End Source File
+# Begin Source File
+
SOURCE=..\..\Archive\LzhHandler.cpp
# End Source File
# Begin Source File
@@ -2905,6 +2913,10 @@ SOURCE=..\..\Archive\RpmHandler.cpp
# End Source File
# Begin Source File
+SOURCE=..\..\Archive\SparseHandler.cpp
+# End Source File
+# Begin Source File
+
SOURCE=..\..\Archive\SplitHandler.cpp
# End Source File
# Begin Source File
@@ -3029,6 +3041,14 @@ SOURCE=..\..\..\Windows\PropVariant.h
# End Source File
# Begin Source File
+SOURCE=..\..\..\Windows\PropVariantConv.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariantConv.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\..\Windows\PropVariantUtils.cpp
# End Source File
# Begin Source File
diff --git a/CPP/7zip/Bundles/Format7zF/Format7z.dsw b/CPP/7zip/Bundles/Format7zF/Format7z.dsw
index 324dab1f..324dab1f 100644..100755
--- a/CPP/7zip/Bundles/Format7zF/Format7z.dsw
+++ b/CPP/7zip/Bundles/Format7zF/Format7z.dsw
diff --git a/CPP/7zip/Bundles/Format7zF/StdAfx.cpp b/CPP/7zip/Bundles/Format7zF/StdAfx.cpp
index d0feea85..d0feea85 100644..100755
--- a/CPP/7zip/Bundles/Format7zF/StdAfx.cpp
+++ b/CPP/7zip/Bundles/Format7zF/StdAfx.cpp
diff --git a/CPP/7zip/Bundles/Format7zF/StdAfx.h b/CPP/7zip/Bundles/Format7zF/StdAfx.h
index 2854ff3e..2854ff3e 100644..100755
--- a/CPP/7zip/Bundles/Format7zF/StdAfx.h
+++ b/CPP/7zip/Bundles/Format7zF/StdAfx.h
diff --git a/CPP/7zip/Bundles/Format7zF/makefile b/CPP/7zip/Bundles/Format7zF/makefile
index 97318dc6..97318dc6 100644..100755
--- a/CPP/7zip/Bundles/Format7zF/makefile
+++ b/CPP/7zip/Bundles/Format7zF/makefile
diff --git a/CPP/7zip/Bundles/Format7zF/makefile.gcc b/CPP/7zip/Bundles/Format7zF/makefile.gcc
index 1953dd55..1953dd55 100644..100755
--- a/CPP/7zip/Bundles/Format7zF/makefile.gcc
+++ b/CPP/7zip/Bundles/Format7zF/makefile.gcc
diff --git a/CPP/7zip/Bundles/Format7zF/resource.rc b/CPP/7zip/Bundles/Format7zF/resource.rc
index aaaabeaa..9c797c15 100644..100755
--- a/CPP/7zip/Bundles/Format7zF/resource.rc
+++ b/CPP/7zip/Bundles/Format7zF/resource.rc
@@ -28,10 +28,11 @@ MY_VERSION_INFO_DLL("7z Plugin" , "7z")
22 ICON "../../Archive/Icons/ntfs.ico"
23 ICON "../../Archive/Icons/xz.ico"
24 ICON "../../Archive/Icons/squashfs.ico"
+25 ICON "../../Archive/Icons/apfs.ico"
STRINGTABLE
BEGIN
- 100 "7z:0 zip:1 rar:3 001:9 cab:7 iso:8 xz:23 txz:23 lzma:16 tar:13 cpio:12 bz2:2 bzip2:2 tbz2:2 tbz:2 gz:14 gzip:14 tgz:14 tpz:14 z:5 taz:5 lzh:6 lha:6 rpm:10 deb:11 arj:4 vhd:20 vhdx:20 wim:15 swm:15 esd:15 fat:21 ntfs:22 dmg:17 hfs:18 xar:19 squashfs:24"
+ 100 "7z:0 zip:1 rar:3 001:9 cab:7 iso:8 xz:23 txz:23 lzma:16 tar:13 cpio:12 bz2:2 bzip2:2 tbz2:2 tbz:2 gz:14 gzip:14 tgz:14 tpz:14 z:5 taz:5 lzh:6 lha:6 rpm:10 deb:11 arj:4 vhd:20 vhdx:20 wim:15 swm:15 esd:15 fat:21 ntfs:22 dmg:17 hfs:18 xar:19 squashfs:24 apfs:25"
END
diff --git a/CPP/7zip/Bundles/Format7zR/StdAfx.cpp b/CPP/7zip/Bundles/Format7zR/StdAfx.cpp
index d0feea85..d0feea85 100644..100755
--- a/CPP/7zip/Bundles/Format7zR/StdAfx.cpp
+++ b/CPP/7zip/Bundles/Format7zR/StdAfx.cpp
diff --git a/CPP/7zip/Bundles/Format7zR/StdAfx.h b/CPP/7zip/Bundles/Format7zR/StdAfx.h
index 2854ff3e..2854ff3e 100644..100755
--- a/CPP/7zip/Bundles/Format7zR/StdAfx.h
+++ b/CPP/7zip/Bundles/Format7zR/StdAfx.h
diff --git a/CPP/7zip/Bundles/Format7zR/makefile b/CPP/7zip/Bundles/Format7zR/makefile
index c2237152..c2237152 100644..100755
--- a/CPP/7zip/Bundles/Format7zR/makefile
+++ b/CPP/7zip/Bundles/Format7zR/makefile
diff --git a/CPP/7zip/Bundles/Format7zR/resource.rc b/CPP/7zip/Bundles/Format7zR/resource.rc
index a8baa596..a8baa596 100644..100755
--- a/CPP/7zip/Bundles/Format7zR/resource.rc
+++ b/CPP/7zip/Bundles/Format7zR/resource.rc
diff --git a/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp b/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp
index a08d9c09..71436f65 100644..100755
--- a/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp
+++ b/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp
@@ -515,7 +515,7 @@ static int main2(int numArgs, const char *args[])
if (inStreamSpec)
{
- if (!inStreamSpec->File.GetLength(fileSize))
+ if (!inStreamSpec->GetLength(fileSize))
throw "Cannot get file length";
fileSizeDefined = true;
if (!stdOutMode)
diff --git a/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsp b/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsp
index d7326efc..d7326efc 100644..100755
--- a/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsp
+++ b/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsp
diff --git a/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsw b/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsw
index e62c9d2f..e62c9d2f 100644..100755
--- a/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsw
+++ b/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsw
diff --git a/CPP/7zip/Bundles/LzmaCon/StdAfx.cpp b/CPP/7zip/Bundles/LzmaCon/StdAfx.cpp
index d0feea85..d0feea85 100644..100755
--- a/CPP/7zip/Bundles/LzmaCon/StdAfx.cpp
+++ b/CPP/7zip/Bundles/LzmaCon/StdAfx.cpp
diff --git a/CPP/7zip/Bundles/LzmaCon/StdAfx.h b/CPP/7zip/Bundles/LzmaCon/StdAfx.h
index 2854ff3e..2854ff3e 100644..100755
--- a/CPP/7zip/Bundles/LzmaCon/StdAfx.h
+++ b/CPP/7zip/Bundles/LzmaCon/StdAfx.h
diff --git a/CPP/7zip/Bundles/LzmaCon/makefile b/CPP/7zip/Bundles/LzmaCon/makefile
index 5e53327a..5e53327a 100644..100755
--- a/CPP/7zip/Bundles/LzmaCon/makefile
+++ b/CPP/7zip/Bundles/LzmaCon/makefile
diff --git a/CPP/7zip/Bundles/LzmaCon/makefile.gcc b/CPP/7zip/Bundles/LzmaCon/makefile.gcc
index 58c204af..58c204af 100644..100755
--- a/CPP/7zip/Bundles/LzmaCon/makefile.gcc
+++ b/CPP/7zip/Bundles/LzmaCon/makefile.gcc
diff --git a/CPP/7zip/Bundles/LzmaCon/resource.rc b/CPP/7zip/Bundles/LzmaCon/resource.rc
index 43b50738..43b50738 100644..100755
--- a/CPP/7zip/Bundles/LzmaCon/resource.rc
+++ b/CPP/7zip/Bundles/LzmaCon/resource.rc
diff --git a/CPP/7zip/Bundles/SFXCon/7z.ico b/CPP/7zip/Bundles/SFXCon/7z.ico
index 47ffb781..47ffb781 100644..100755
--- a/CPP/7zip/Bundles/SFXCon/7z.ico
+++ b/CPP/7zip/Bundles/SFXCon/7z.ico
Binary files differ
diff --git a/CPP/7zip/Bundles/SFXCon/SFXCon.dsp b/CPP/7zip/Bundles/SFXCon/SFXCon.dsp
index 87e27c4f..87e27c4f 100644..100755
--- a/CPP/7zip/Bundles/SFXCon/SFXCon.dsp
+++ b/CPP/7zip/Bundles/SFXCon/SFXCon.dsp
diff --git a/CPP/7zip/Bundles/SFXCon/SFXCon.dsw b/CPP/7zip/Bundles/SFXCon/SFXCon.dsw
index 27bf7e6d..27bf7e6d 100644..100755
--- a/CPP/7zip/Bundles/SFXCon/SFXCon.dsw
+++ b/CPP/7zip/Bundles/SFXCon/SFXCon.dsw
diff --git a/CPP/7zip/Bundles/SFXCon/SfxCon.cpp b/CPP/7zip/Bundles/SFXCon/SfxCon.cpp
index cfa1ee7c..cfa1ee7c 100644..100755
--- a/CPP/7zip/Bundles/SFXCon/SfxCon.cpp
+++ b/CPP/7zip/Bundles/SFXCon/SfxCon.cpp
diff --git a/CPP/7zip/Bundles/SFXCon/StdAfx.cpp b/CPP/7zip/Bundles/SFXCon/StdAfx.cpp
index d0feea85..d0feea85 100644..100755
--- a/CPP/7zip/Bundles/SFXCon/StdAfx.cpp
+++ b/CPP/7zip/Bundles/SFXCon/StdAfx.cpp
diff --git a/CPP/7zip/Bundles/SFXCon/StdAfx.h b/CPP/7zip/Bundles/SFXCon/StdAfx.h
index 2854ff3e..2854ff3e 100644..100755
--- a/CPP/7zip/Bundles/SFXCon/StdAfx.h
+++ b/CPP/7zip/Bundles/SFXCon/StdAfx.h
diff --git a/CPP/7zip/Bundles/SFXCon/makefile b/CPP/7zip/Bundles/SFXCon/makefile
index 633bd775..633bd775 100644..100755
--- a/CPP/7zip/Bundles/SFXCon/makefile
+++ b/CPP/7zip/Bundles/SFXCon/makefile
diff --git a/CPP/7zip/Bundles/SFXCon/makefile.gcc b/CPP/7zip/Bundles/SFXCon/makefile.gcc
index 889ec1f9..889ec1f9 100644..100755
--- a/CPP/7zip/Bundles/SFXCon/makefile.gcc
+++ b/CPP/7zip/Bundles/SFXCon/makefile.gcc
diff --git a/CPP/7zip/Bundles/SFXCon/resource.rc b/CPP/7zip/Bundles/SFXCon/resource.rc
index 58331b81..58331b81 100644..100755
--- a/CPP/7zip/Bundles/SFXCon/resource.rc
+++ b/CPP/7zip/Bundles/SFXCon/resource.rc
diff --git a/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp b/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp
index 8eaeabe7..8eaeabe7 100644..100755
--- a/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp
+++ b/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp
diff --git a/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.h b/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.h
index cfbc5c07..cfbc5c07 100644..100755
--- a/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.h
+++ b/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.h
diff --git a/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp b/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp
index 71b65c62..71b65c62 100644..100755
--- a/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp
+++ b/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp
diff --git a/CPP/7zip/Bundles/SFXSetup/ExtractEngine.h b/CPP/7zip/Bundles/SFXSetup/ExtractEngine.h
index 295d77b9..295d77b9 100644..100755
--- a/CPP/7zip/Bundles/SFXSetup/ExtractEngine.h
+++ b/CPP/7zip/Bundles/SFXSetup/ExtractEngine.h
diff --git a/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp b/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp
index 754cc0e0..754cc0e0 100644..100755
--- a/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp
+++ b/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp
diff --git a/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsw b/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsw
index f563b21f..f563b21f 100644..100755
--- a/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsw
+++ b/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsw
diff --git a/CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp b/CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp
index 86b4f0fb..86b4f0fb 100644..100755
--- a/CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp
+++ b/CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp
diff --git a/CPP/7zip/Bundles/SFXSetup/StdAfx.cpp b/CPP/7zip/Bundles/SFXSetup/StdAfx.cpp
index d0feea85..d0feea85 100644..100755
--- a/CPP/7zip/Bundles/SFXSetup/StdAfx.cpp
+++ b/CPP/7zip/Bundles/SFXSetup/StdAfx.cpp
diff --git a/CPP/7zip/Bundles/SFXSetup/StdAfx.h b/CPP/7zip/Bundles/SFXSetup/StdAfx.h
index 37bbd0c3..37bbd0c3 100644..100755
--- a/CPP/7zip/Bundles/SFXSetup/StdAfx.h
+++ b/CPP/7zip/Bundles/SFXSetup/StdAfx.h
diff --git a/CPP/7zip/Bundles/SFXSetup/makefile b/CPP/7zip/Bundles/SFXSetup/makefile
index 9fddbc07..9fddbc07 100644..100755
--- a/CPP/7zip/Bundles/SFXSetup/makefile
+++ b/CPP/7zip/Bundles/SFXSetup/makefile
diff --git a/CPP/7zip/Bundles/SFXSetup/resource.h b/CPP/7zip/Bundles/SFXSetup/resource.h
index d5f440bb..d5f440bb 100644..100755
--- a/CPP/7zip/Bundles/SFXSetup/resource.h
+++ b/CPP/7zip/Bundles/SFXSetup/resource.h
diff --git a/CPP/7zip/Bundles/SFXSetup/resource.rc b/CPP/7zip/Bundles/SFXSetup/resource.rc
index 47e1b762..47e1b762 100644..100755
--- a/CPP/7zip/Bundles/SFXSetup/resource.rc
+++ b/CPP/7zip/Bundles/SFXSetup/resource.rc
diff --git a/CPP/7zip/Bundles/SFXSetup/setup.ico b/CPP/7zip/Bundles/SFXSetup/setup.ico
index bb455be1..bb455be1 100644..100755
--- a/CPP/7zip/Bundles/SFXSetup/setup.ico
+++ b/CPP/7zip/Bundles/SFXSetup/setup.ico
Binary files differ
diff --git a/CPP/7zip/Bundles/SFXWin/7z.ico b/CPP/7zip/Bundles/SFXWin/7z.ico
index 47ffb781..47ffb781 100644..100755
--- a/CPP/7zip/Bundles/SFXWin/7z.ico
+++ b/CPP/7zip/Bundles/SFXWin/7z.ico
Binary files differ
diff --git a/CPP/7zip/Bundles/SFXWin/SFXWin.dsp b/CPP/7zip/Bundles/SFXWin/SFXWin.dsp
index 8e1a70d2..8e1a70d2 100644..100755
--- a/CPP/7zip/Bundles/SFXWin/SFXWin.dsp
+++ b/CPP/7zip/Bundles/SFXWin/SFXWin.dsp
diff --git a/CPP/7zip/Bundles/SFXWin/SFXWin.dsw b/CPP/7zip/Bundles/SFXWin/SFXWin.dsw
index a9926c71..a9926c71 100644..100755
--- a/CPP/7zip/Bundles/SFXWin/SFXWin.dsw
+++ b/CPP/7zip/Bundles/SFXWin/SFXWin.dsw
diff --git a/CPP/7zip/Bundles/SFXWin/SfxWin.cpp b/CPP/7zip/Bundles/SFXWin/SfxWin.cpp
index 23beade2..23beade2 100644..100755
--- a/CPP/7zip/Bundles/SFXWin/SfxWin.cpp
+++ b/CPP/7zip/Bundles/SFXWin/SfxWin.cpp
diff --git a/CPP/7zip/Bundles/SFXWin/StdAfx.cpp b/CPP/7zip/Bundles/SFXWin/StdAfx.cpp
index d0feea85..d0feea85 100644..100755
--- a/CPP/7zip/Bundles/SFXWin/StdAfx.cpp
+++ b/CPP/7zip/Bundles/SFXWin/StdAfx.cpp
diff --git a/CPP/7zip/Bundles/SFXWin/StdAfx.h b/CPP/7zip/Bundles/SFXWin/StdAfx.h
index 975a17e8..975a17e8 100644..100755
--- a/CPP/7zip/Bundles/SFXWin/StdAfx.h
+++ b/CPP/7zip/Bundles/SFXWin/StdAfx.h
diff --git a/CPP/7zip/Bundles/SFXWin/makefile b/CPP/7zip/Bundles/SFXWin/makefile
index 0ed36f8a..0ed36f8a 100644..100755
--- a/CPP/7zip/Bundles/SFXWin/makefile
+++ b/CPP/7zip/Bundles/SFXWin/makefile
diff --git a/CPP/7zip/Bundles/SFXWin/resource.h b/CPP/7zip/Bundles/SFXWin/resource.h
index 30fe2030..30fe2030 100644..100755
--- a/CPP/7zip/Bundles/SFXWin/resource.h
+++ b/CPP/7zip/Bundles/SFXWin/resource.h
diff --git a/CPP/7zip/Bundles/SFXWin/resource.rc b/CPP/7zip/Bundles/SFXWin/resource.rc
index 91292b2f..91292b2f 100644..100755
--- a/CPP/7zip/Bundles/SFXWin/resource.rc
+++ b/CPP/7zip/Bundles/SFXWin/resource.rc
diff --git a/CPP/7zip/Bundles/makefile b/CPP/7zip/Bundles/makefile
index 0651da54..0651da54 100644..100755
--- a/CPP/7zip/Bundles/makefile
+++ b/CPP/7zip/Bundles/makefile
diff --git a/CPP/7zip/Common/CWrappers.cpp b/CPP/7zip/Common/CWrappers.cpp
index ee4c36a2..ee4c36a2 100644..100755
--- a/CPP/7zip/Common/CWrappers.cpp
+++ b/CPP/7zip/Common/CWrappers.cpp
diff --git a/CPP/7zip/Common/CWrappers.h b/CPP/7zip/Common/CWrappers.h
index e7196a5c..e7196a5c 100644..100755
--- a/CPP/7zip/Common/CWrappers.h
+++ b/CPP/7zip/Common/CWrappers.h
diff --git a/CPP/7zip/Common/CreateCoder.cpp b/CPP/7zip/Common/CreateCoder.cpp
index 872f17fc..872f17fc 100644..100755
--- a/CPP/7zip/Common/CreateCoder.cpp
+++ b/CPP/7zip/Common/CreateCoder.cpp
diff --git a/CPP/7zip/Common/CreateCoder.h b/CPP/7zip/Common/CreateCoder.h
index 24e6b663..24e6b663 100644..100755
--- a/CPP/7zip/Common/CreateCoder.h
+++ b/CPP/7zip/Common/CreateCoder.h
diff --git a/CPP/7zip/Common/FilePathAutoRename.cpp b/CPP/7zip/Common/FilePathAutoRename.cpp
index 1ebfd72b..1ebfd72b 100644..100755
--- a/CPP/7zip/Common/FilePathAutoRename.cpp
+++ b/CPP/7zip/Common/FilePathAutoRename.cpp
diff --git a/CPP/7zip/Common/FilePathAutoRename.h b/CPP/7zip/Common/FilePathAutoRename.h
index 7b576591..7b576591 100644..100755
--- a/CPP/7zip/Common/FilePathAutoRename.h
+++ b/CPP/7zip/Common/FilePathAutoRename.h
diff --git a/CPP/7zip/Common/FileStreams.cpp b/CPP/7zip/Common/FileStreams.cpp
index 9e0e79ca..6862a9b6 100644..100755
--- a/CPP/7zip/Common/FileStreams.cpp
+++ b/CPP/7zip/Common/FileStreams.cpp
@@ -2,18 +2,30 @@
#include "StdAfx.h"
+// #include <stdio.h>
+
#ifndef _WIN32
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
-#include "../../Windows/FileFind.h"
+#include <grp.h>
+#include <pwd.h>
+
+// for major minor
+// BSD: <sys/types.h>
+#include <sys/sysmacros.h>
+
#endif
+#include "../../Windows/FileFind.h"
+
#ifdef SUPPORT_DEVICE_FILE
#include "../../../C/Alloc.h"
#include "../../Common/Defs.h"
#endif
+#include "../PropID.h"
+
#include "FileStreams.h"
static inline HRESULT GetLastError_HRESULT()
@@ -37,12 +49,19 @@ static const UInt32 kClusterSize = 1 << 18;
#endif
CInFileStream::CInFileStream():
- #ifdef SUPPORT_DEVICE_FILE
+ #ifdef SUPPORT_DEVICE_FILE
VirtPos(0),
PhyPos(0),
Buf(0),
BufSize(0),
- #endif
+ #endif
+ #ifndef _WIN32
+ _uid(0),
+ _gid(0),
+ StoreOwnerId(false),
+ StoreOwnerName(false),
+ #endif
+ _info_WasLoaded(false),
SupportHardLinks(false),
Callback(NULL),
CallbackRef(0)
@@ -56,7 +75,7 @@ CInFileStream::~CInFileStream()
#endif
if (Callback)
- Callback->InFileStream_On_Destroy(CallbackRef);
+ Callback->InFileStream_On_Destroy(this, CallbackRef);
}
STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
@@ -306,8 +325,14 @@ STDMETHODIMP CInFileStream::GetSize(UInt64 *size)
STDMETHODIMP 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;
@@ -316,13 +341,18 @@ STDMETHODIMP CInFileStream::GetProps(UInt64 *size, FILETIME *cTime, FILETIME *aT
if (attrib) *attrib = info.dwFileAttributes;
return S_OK;
}
- return GetLastError_HRESULT();
}
STDMETHODIMP 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;
@@ -335,27 +365,114 @@ STDMETHODIMP CInFileStream::GetProps2(CStreamFileProps *props)
props->MTime = info.ftLastWriteTime;
return S_OK;
}
- return GetLastError_HRESULT();
}
+STDMETHODIMP CInFileStream::GetProperty(PROPID propID, PROPVARIANT *value)
+{
+ if (!_info_WasLoaded)
+ RINOK(ReloadProps());
+
+ if (!_info_WasLoaded)
+ return S_OK;
+
+ NWindows::NCOM::CPropVariant prop;
+
+ #ifdef SUPPORT_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;
+}
+
+
+STDMETHODIMP CInFileStream::ReloadProps()
+{
+ #ifdef SUPPORT_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)
STDMETHODIMP 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;
- #ifdef __APPLE__
- if (cTime) NWindows::NFile::NFind::timespec_To_FILETIME(st.st_ctimespec, *cTime);
- if (aTime) NWindows::NFile::NFind::timespec_To_FILETIME(st.st_atimespec, *aTime);
- if (mTime) NWindows::NFile::NFind::timespec_To_FILETIME(st.st_mtimespec, *mTime);
- #else
- if (cTime) NWindows::NFile::NFind::timespec_To_FILETIME(st.st_ctim, *cTime);
- if (aTime) NWindows::NFile::NFind::timespec_To_FILETIME(st.st_atim, *aTime);
- if (mTime) NWindows::NFile::NFind::timespec_To_FILETIME(st.st_mtim, *mTime);
- #endif
+ 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;
@@ -365,9 +482,14 @@ STDMETHODIMP CInFileStream::GetProps(UInt64 *size, FILETIME *cTime, FILETIME *aT
STDMETHODIMP 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;
/*
@@ -381,15 +503,9 @@ STDMETHODIMP CInFileStream::GetProps2(CStreamFileProps *props)
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);
- #ifdef __APPLE__
- NWindows::NFile::NFind::timespec_To_FILETIME(st.st_ctimespec, props->CTime);
- NWindows::NFile::NFind::timespec_To_FILETIME(st.st_atimespec, props->ATime);
- NWindows::NFile::NFind::timespec_To_FILETIME(st.st_mtimespec, props->MTime);
- #else
- NWindows::NFile::NFind::timespec_To_FILETIME(st.st_ctim, props->CTime);
- NWindows::NFile::NFind::timespec_To_FILETIME(st.st_atim, props->ATime);
- NWindows::NFile::NFind::timespec_To_FILETIME(st.st_mtim, props->MTime);
- #endif
+ 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"
@@ -402,8 +518,130 @@ STDMETHODIMP CInFileStream::GetProps2(CStreamFileProps *props)
return S_OK;
}
+STDMETHODIMP 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;
+
+ 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;
+
+ /*
+ 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;
+}
+
+
+STDMETHODIMP CInFileStream::ReloadProps()
+{
+ _info_WasLoaded = (File.my_fstat(&_info) == 0);
+ if (!_info_WasLoaded)
+ return GetLastError_HRESULT();
+ return S_OK;
+}
+
#endif
+
+
+
//////////////////////////
// COutFileStream
diff --git a/CPP/7zip/Common/FileStreams.h b/CPP/7zip/Common/FileStreams.h
index fe9f4c19..f2c19eea 100644..100755
--- a/CPP/7zip/Common/FileStreams.h
+++ b/CPP/7zip/Common/FileStreams.h
@@ -14,10 +14,14 @@
#include "../IStream.h"
+#include "UniqBlocks.h"
+
+
+class CInFileStream;
struct IInFileStream_Callback
{
virtual HRESULT InFileStream_On_Error(UINT_PTR val, DWORD error) = 0;
- virtual void InFileStream_On_Destroy(UINT_PTR val) = 0;
+ virtual void InFileStream_On_Destroy(CInFileStream *stream, UINT_PTR val) = 0;
};
class CInFileStream:
@@ -25,10 +29,11 @@ class CInFileStream:
public IStreamGetSize,
public IStreamGetProps,
public IStreamGetProps2,
+ public IStreamGetProp,
public CMyUnknownImp
{
-public:
NWindows::NFile::NIO::CInFile File;
+public:
#ifdef USE_WIN_FILE
@@ -42,22 +47,46 @@ public:
#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;
UINT_PTR CallbackRef;
virtual ~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);
}
@@ -65,6 +94,7 @@ public:
MY_QUERYINTERFACE_ENTRY(IStreamGetSize)
MY_QUERYINTERFACE_ENTRY(IStreamGetProps)
MY_QUERYINTERFACE_ENTRY(IStreamGetProps2)
+ MY_QUERYINTERFACE_ENTRY(IStreamGetProp)
MY_QUERYINTERFACE_END
MY_ADDREF_RELEASE
@@ -74,6 +104,8 @@ public:
STDMETHOD(GetSize)(UInt64 *size);
STDMETHOD(GetProps)(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib);
STDMETHOD(GetProps2)(CStreamFileProps *props);
+ STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value);
+ STDMETHOD(ReloadProps)();
};
class CStdInFileStream:
@@ -110,11 +142,11 @@ public:
UInt64 ProcessedSize;
- 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); }
+ bool SetMTime(const CFiTime *mTime) { return File.SetMTime(mTime); }
MY_UNKNOWN_IMP1(IOutStream)
diff --git a/CPP/7zip/Common/FilterCoder.cpp b/CPP/7zip/Common/FilterCoder.cpp
index fb99f610..fb99f610 100644..100755
--- a/CPP/7zip/Common/FilterCoder.cpp
+++ b/CPP/7zip/Common/FilterCoder.cpp
diff --git a/CPP/7zip/Common/FilterCoder.h b/CPP/7zip/Common/FilterCoder.h
index 6668fdb3..6668fdb3 100644..100755
--- a/CPP/7zip/Common/FilterCoder.h
+++ b/CPP/7zip/Common/FilterCoder.h
diff --git a/CPP/7zip/Common/InBuffer.cpp b/CPP/7zip/Common/InBuffer.cpp
index 6f6eecad..fe6d1490 100644..100755
--- a/CPP/7zip/Common/InBuffer.cpp
+++ b/CPP/7zip/Common/InBuffer.cpp
@@ -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;
}
diff --git a/CPP/7zip/Common/InBuffer.h b/CPP/7zip/Common/InBuffer.h
index fa063949..fa063949 100644..100755
--- a/CPP/7zip/Common/InBuffer.h
+++ b/CPP/7zip/Common/InBuffer.h
diff --git a/CPP/7zip/Common/InOutTempBuffer.cpp b/CPP/7zip/Common/InOutTempBuffer.cpp
index cae6b803..cae6b803 100644..100755
--- a/CPP/7zip/Common/InOutTempBuffer.cpp
+++ b/CPP/7zip/Common/InOutTempBuffer.cpp
diff --git a/CPP/7zip/Common/InOutTempBuffer.h b/CPP/7zip/Common/InOutTempBuffer.h
index 755935ea..755935ea 100644..100755
--- a/CPP/7zip/Common/InOutTempBuffer.h
+++ b/CPP/7zip/Common/InOutTempBuffer.h
diff --git a/CPP/7zip/Common/LimitedStreams.cpp b/CPP/7zip/Common/LimitedStreams.cpp
index add6636b..980c795d 100644..100755
--- a/CPP/7zip/Common/LimitedStreams.cpp
+++ b/CPP/7zip/Common/LimitedStreams.cpp
@@ -154,44 +154,70 @@ STDMETHODIMP 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(Stream->Seek((Int64)phy, STREAM_SEEK_SET, NULL));
+ _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)
{
switch (seekOrigin)
diff --git a/CPP/7zip/Common/LimitedStreams.h b/CPP/7zip/Common/LimitedStreams.h
index ade29937..50c7cd85 100644..100755
--- a/CPP/7zip/Common/LimitedStreams.h
+++ b/CPP/7zip/Common/LimitedStreams.h
@@ -101,21 +101,26 @@ public:
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;
+
+ void SetAs_ZeroFill() { Phy = k_SeekExtent_Phy_Type_ZeroFill; }
+ bool Is_ZeroFill() const { return Phy == k_SeekExtent_Phy_Type_ZeroFill; }
};
class CExtentsStream:
public IInStream,
public CMyUnknownImp
{
- UInt64 _phyPos;
UInt64 _virtPos;
- bool _needStartSeek;
-
- HRESULT SeekToPhys() { return Stream->Seek((Int64)_phyPos, STREAM_SEEK_SET, NULL); }
+ UInt64 _phyPos;
+ unsigned _prevExtentIndex;
public:
CMyComPtr<IInStream> Stream;
@@ -129,11 +134,13 @@ public:
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
diff --git a/CPP/7zip/Common/LockedStream.cpp b/CPP/7zip/Common/LockedStream.cpp
index ca39fb45..ca39fb45 100644..100755
--- a/CPP/7zip/Common/LockedStream.cpp
+++ b/CPP/7zip/Common/LockedStream.cpp
diff --git a/CPP/7zip/Common/LockedStream.h b/CPP/7zip/Common/LockedStream.h
index efebf197..efebf197 100644..100755
--- a/CPP/7zip/Common/LockedStream.h
+++ b/CPP/7zip/Common/LockedStream.h
diff --git a/CPP/7zip/Common/MemBlocks.cpp b/CPP/7zip/Common/MemBlocks.cpp
index 9b0652c6..9b0652c6 100644..100755
--- a/CPP/7zip/Common/MemBlocks.cpp
+++ b/CPP/7zip/Common/MemBlocks.cpp
diff --git a/CPP/7zip/Common/MemBlocks.h b/CPP/7zip/Common/MemBlocks.h
index 3c9cefdb..3c9cefdb 100644..100755
--- a/CPP/7zip/Common/MemBlocks.h
+++ b/CPP/7zip/Common/MemBlocks.h
diff --git a/CPP/7zip/Common/MethodId.cpp b/CPP/7zip/Common/MethodId.cpp
index 1566c97c..1566c97c 100644..100755
--- a/CPP/7zip/Common/MethodId.cpp
+++ b/CPP/7zip/Common/MethodId.cpp
diff --git a/CPP/7zip/Common/MethodId.h b/CPP/7zip/Common/MethodId.h
index 28b615fc..28b615fc 100644..100755
--- a/CPP/7zip/Common/MethodId.h
+++ b/CPP/7zip/Common/MethodId.h
diff --git a/CPP/7zip/Common/MethodProps.cpp b/CPP/7zip/Common/MethodProps.cpp
index 0e8ff1c6..0e8ff1c6 100644..100755
--- a/CPP/7zip/Common/MethodProps.cpp
+++ b/CPP/7zip/Common/MethodProps.cpp
diff --git a/CPP/7zip/Common/MethodProps.h b/CPP/7zip/Common/MethodProps.h
index 5b5c96a4..5b5c96a4 100644..100755
--- a/CPP/7zip/Common/MethodProps.h
+++ b/CPP/7zip/Common/MethodProps.h
diff --git a/CPP/7zip/Common/OffsetStream.cpp b/CPP/7zip/Common/OffsetStream.cpp
index b16124c2..b16124c2 100644..100755
--- a/CPP/7zip/Common/OffsetStream.cpp
+++ b/CPP/7zip/Common/OffsetStream.cpp
diff --git a/CPP/7zip/Common/OffsetStream.h b/CPP/7zip/Common/OffsetStream.h
index 9074a24e..9074a24e 100644..100755
--- a/CPP/7zip/Common/OffsetStream.h
+++ b/CPP/7zip/Common/OffsetStream.h
diff --git a/CPP/7zip/Common/OutBuffer.cpp b/CPP/7zip/Common/OutBuffer.cpp
index 4ba34a05..4ba34a05 100644..100755
--- a/CPP/7zip/Common/OutBuffer.cpp
+++ b/CPP/7zip/Common/OutBuffer.cpp
diff --git a/CPP/7zip/Common/OutBuffer.h b/CPP/7zip/Common/OutBuffer.h
index d7ca9f6a..d7ca9f6a 100644..100755
--- a/CPP/7zip/Common/OutBuffer.h
+++ b/CPP/7zip/Common/OutBuffer.h
diff --git a/CPP/7zip/Common/OutMemStream.cpp b/CPP/7zip/Common/OutMemStream.cpp
index 241589d2..241589d2 100644..100755
--- a/CPP/7zip/Common/OutMemStream.cpp
+++ b/CPP/7zip/Common/OutMemStream.cpp
diff --git a/CPP/7zip/Common/OutMemStream.h b/CPP/7zip/Common/OutMemStream.h
index 873742ed..873742ed 100644..100755
--- a/CPP/7zip/Common/OutMemStream.h
+++ b/CPP/7zip/Common/OutMemStream.h
diff --git a/CPP/7zip/Common/ProgressMt.cpp b/CPP/7zip/Common/ProgressMt.cpp
index c2714a27..c2714a27 100644..100755
--- a/CPP/7zip/Common/ProgressMt.cpp
+++ b/CPP/7zip/Common/ProgressMt.cpp
diff --git a/CPP/7zip/Common/ProgressMt.h b/CPP/7zip/Common/ProgressMt.h
index 32da976b..32da976b 100644..100755
--- a/CPP/7zip/Common/ProgressMt.h
+++ b/CPP/7zip/Common/ProgressMt.h
diff --git a/CPP/7zip/Common/ProgressUtils.cpp b/CPP/7zip/Common/ProgressUtils.cpp
index 41385ccb..41385ccb 100644..100755
--- a/CPP/7zip/Common/ProgressUtils.cpp
+++ b/CPP/7zip/Common/ProgressUtils.cpp
diff --git a/CPP/7zip/Common/ProgressUtils.h b/CPP/7zip/Common/ProgressUtils.h
index e94265ba..e94265ba 100644..100755
--- a/CPP/7zip/Common/ProgressUtils.h
+++ b/CPP/7zip/Common/ProgressUtils.h
diff --git a/CPP/7zip/Common/PropId.cpp b/CPP/7zip/Common/PropId.cpp
index 11d20d55..0e643e85 100644..100755
--- a/CPP/7zip/Common/PropId.cpp
+++ b/CPP/7zip/Common/PropId.cpp
@@ -104,5 +104,12 @@ 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 // kpidDeviceMinor
};
diff --git a/CPP/7zip/Common/RegisterArc.h b/CPP/7zip/Common/RegisterArc.h
index 3421ba1b..a0384fad 100644..100755
--- a/CPP/7zip/Common/RegisterArc.h
+++ b/CPP/7zip/Common/RegisterArc.h
@@ -7,7 +7,7 @@
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;
@@ -39,22 +41,22 @@ void RegisterArc(const CArcInfo *arcInfo) throw();
#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, 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, 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, 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/CPP/7zip/Common/RegisterCodec.h b/CPP/7zip/Common/RegisterCodec.h
index a942da7a..a942da7a 100644..100755
--- a/CPP/7zip/Common/RegisterCodec.h
+++ b/CPP/7zip/Common/RegisterCodec.h
diff --git a/CPP/7zip/Common/StdAfx.h b/CPP/7zip/Common/StdAfx.h
index 1cbd7fea..1cbd7fea 100644..100755
--- a/CPP/7zip/Common/StdAfx.h
+++ b/CPP/7zip/Common/StdAfx.h
diff --git a/CPP/7zip/Common/StreamBinder.cpp b/CPP/7zip/Common/StreamBinder.cpp
index 6b6e0e58..6b6e0e58 100644..100755
--- a/CPP/7zip/Common/StreamBinder.cpp
+++ b/CPP/7zip/Common/StreamBinder.cpp
diff --git a/CPP/7zip/Common/StreamBinder.h b/CPP/7zip/Common/StreamBinder.h
index 16c872fb..16c872fb 100644..100755
--- a/CPP/7zip/Common/StreamBinder.h
+++ b/CPP/7zip/Common/StreamBinder.h
diff --git a/CPP/7zip/Common/StreamObjects.cpp b/CPP/7zip/Common/StreamObjects.cpp
index 2d941df6..2d941df6 100644..100755
--- a/CPP/7zip/Common/StreamObjects.cpp
+++ b/CPP/7zip/Common/StreamObjects.cpp
diff --git a/CPP/7zip/Common/StreamObjects.h b/CPP/7zip/Common/StreamObjects.h
index a8fb229c..a8fb229c 100644..100755
--- a/CPP/7zip/Common/StreamObjects.h
+++ b/CPP/7zip/Common/StreamObjects.h
diff --git a/CPP/7zip/Common/StreamUtils.cpp b/CPP/7zip/Common/StreamUtils.cpp
index 1402f420..1402f420 100644..100755
--- a/CPP/7zip/Common/StreamUtils.cpp
+++ b/CPP/7zip/Common/StreamUtils.cpp
diff --git a/CPP/7zip/Common/StreamUtils.h b/CPP/7zip/Common/StreamUtils.h
index ae914c00..ae914c00 100644..100755
--- a/CPP/7zip/Common/StreamUtils.h
+++ b/CPP/7zip/Common/StreamUtils.h
diff --git a/CPP/7zip/Common/UniqBlocks.cpp b/CPP/7zip/Common/UniqBlocks.cpp
index 8f754e17..32dc2762 100644..100755
--- a/CPP/7zip/Common/UniqBlocks.cpp
+++ b/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/CPP/7zip/Common/UniqBlocks.h b/CPP/7zip/Common/UniqBlocks.h
index d6cd3728..8479d68c 100644..100755
--- a/CPP/7zip/Common/UniqBlocks.h
+++ b/CPP/7zip/Common/UniqBlocks.h
@@ -3,9 +3,24 @@
#ifndef __UNIQ_BLOCKS_H
#define __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
{
diff --git a/CPP/7zip/Common/VirtThread.cpp b/CPP/7zip/Common/VirtThread.cpp
index bf24bb1c..bf24bb1c 100644..100755
--- a/CPP/7zip/Common/VirtThread.cpp
+++ b/CPP/7zip/Common/VirtThread.cpp
diff --git a/CPP/7zip/Common/VirtThread.h b/CPP/7zip/Common/VirtThread.h
index b4d8a5a9..b4d8a5a9 100644..100755
--- a/CPP/7zip/Common/VirtThread.h
+++ b/CPP/7zip/Common/VirtThread.h
diff --git a/CPP/7zip/Compress/BZip2Const.h b/CPP/7zip/Compress/BZip2Const.h
index 7927d018..7927d018 100644..100755
--- a/CPP/7zip/Compress/BZip2Const.h
+++ b/CPP/7zip/Compress/BZip2Const.h
diff --git a/CPP/7zip/Compress/BZip2Crc.cpp b/CPP/7zip/Compress/BZip2Crc.cpp
index 9639c7b7..9639c7b7 100644..100755
--- a/CPP/7zip/Compress/BZip2Crc.cpp
+++ b/CPP/7zip/Compress/BZip2Crc.cpp
diff --git a/CPP/7zip/Compress/BZip2Crc.h b/CPP/7zip/Compress/BZip2Crc.h
index 3b16c60b..3b16c60b 100644..100755
--- a/CPP/7zip/Compress/BZip2Crc.h
+++ b/CPP/7zip/Compress/BZip2Crc.h
diff --git a/CPP/7zip/Compress/BZip2Decoder.cpp b/CPP/7zip/Compress/BZip2Decoder.cpp
index c09c160e..c09c160e 100644..100755
--- a/CPP/7zip/Compress/BZip2Decoder.cpp
+++ b/CPP/7zip/Compress/BZip2Decoder.cpp
diff --git a/CPP/7zip/Compress/BZip2Decoder.h b/CPP/7zip/Compress/BZip2Decoder.h
index 8fe4ef1b..8fe4ef1b 100644..100755
--- a/CPP/7zip/Compress/BZip2Decoder.h
+++ b/CPP/7zip/Compress/BZip2Decoder.h
diff --git a/CPP/7zip/Compress/BZip2Encoder.cpp b/CPP/7zip/Compress/BZip2Encoder.cpp
index 25c3f045..62c15d67 100644..100755
--- a/CPP/7zip/Compress/BZip2Encoder.cpp
+++ b/CPP/7zip/Compress/BZip2Encoder.cpp
@@ -98,8 +98,8 @@ THREAD_FUNC_RET_TYPE CThreadInfo::ThreadFunc()
bool needLeave = true;
try
{
- UInt32 blockSize = Encoder->ReadRleBlock(m_Block);
- m_PackSize = Encoder->m_InStream.GetProcessedSize();
+ const UInt32 blockSize = Encoder->ReadRleBlock(m_Block);
+ m_UnpackSize = Encoder->m_InStream.GetProcessedSize();
m_BlockIndex = Encoder->NextBlockIndex;
if (++Encoder->NextBlockIndex == Encoder->NumThreads)
Encoder->NextBlockIndex = 0;
@@ -222,7 +222,8 @@ UInt32 CEncoder::ReadRleBlock(Byte *buffer)
Byte prevByte;
if (m_InStream.ReadByte(prevByte))
{
- UInt32 blockSize = _props.BlockSizeMult * kBlockSizeStep - 1;
+ NumBlocks++;
+ const UInt32 blockSize = _props.BlockSizeMult * kBlockSizeStep - 1;
unsigned numReps = 1;
buffer[i++] = prevByte;
while (i < blockSize) // "- 1" to support RLE
@@ -722,8 +723,8 @@ HRESULT CThreadInfo::EncodeBlock3(UInt32 blockSize)
if (Encoder->Progress)
{
- UInt64 unpackSize = Encoder->m_OutStream.GetProcessedSize();
- res = Encoder->Progress->SetRatioInfo(&m_PackSize, &unpackSize);
+ const UInt64 packSize = Encoder->m_OutStream.GetProcessedSize();
+ res = Encoder->Progress->SetRatioInfo(&m_UnpackSize, &packSize);
}
Encoder->ThreadsInfo[blockIndex].CanWriteEvent.Set();
@@ -744,6 +745,7 @@ void CEncoder::WriteBytes(const Byte *data, UInt32 sizeInBits, Byte lastByte)
HRESULT CEncoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)
{
+ NumBlocks = 0;
#ifndef _7ZIP_ST
Progress = progress;
RINOK(Create());
@@ -831,9 +833,9 @@ HRESULT CEncoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
RINOK(ti.EncodeBlock3(blockSize));
if (progress)
{
- UInt64 packSize = m_InStream.GetProcessedSize();
- UInt64 unpackSize = m_OutStream.GetProcessedSize();
- RINOK(progress->SetRatioInfo(&packSize, &unpackSize));
+ const UInt64 unpackSize = m_InStream.GetProcessedSize();
+ const UInt64 packSize = m_OutStream.GetProcessedSize();
+ RINOK(progress->SetRatioInfo(&unpackSize, &packSize));
}
}
}
@@ -845,7 +847,10 @@ HRESULT CEncoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
WriteByte(kFinSig5);
WriteCrc(CombinedCrc.GetDigest());
- return Flush();
+ RINOK(Flush());
+ if (!m_InStream.WasFinished())
+ return E_FAIL;
+ return S_OK;
}
STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
diff --git a/CPP/7zip/Compress/BZip2Encoder.h b/CPP/7zip/Compress/BZip2Encoder.h
index 5e63a730..e2828a92 100644..100755
--- a/CPP/7zip/Compress/BZip2Encoder.h
+++ b/CPP/7zip/Compress/BZip2Encoder.h
@@ -129,7 +129,7 @@ public:
// it's not member of this thread. We just need one event per thread
NWindows::NSynchronization::CAutoResetEvent CanWriteEvent;
- UInt64 m_PackSize;
+ UInt64 m_UnpackSize;
Byte MtPad[1 << 8]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size.
HRESULT Create();
@@ -195,6 +195,10 @@ public:
CThreadInfo ThreadsInfo;
#endif
+ UInt64 NumBlocks;
+
+ UInt64 GetInProcessedSize() const { return m_InStream.GetProcessedSize(); }
+
UInt32 ReadRleBlock(Byte *buf);
void WriteBytes(const Byte *data, UInt32 sizeInBits, Byte lastByte);
diff --git a/CPP/7zip/Compress/BZip2Register.cpp b/CPP/7zip/Compress/BZip2Register.cpp
index 6e960366..6e960366 100644..100755
--- a/CPP/7zip/Compress/BZip2Register.cpp
+++ b/CPP/7zip/Compress/BZip2Register.cpp
diff --git a/CPP/7zip/Compress/Bcj2Coder.cpp b/CPP/7zip/Compress/Bcj2Coder.cpp
index 561fd08b..561fd08b 100644..100755
--- a/CPP/7zip/Compress/Bcj2Coder.cpp
+++ b/CPP/7zip/Compress/Bcj2Coder.cpp
diff --git a/CPP/7zip/Compress/Bcj2Coder.h b/CPP/7zip/Compress/Bcj2Coder.h
index ca6a1e4e..ca6a1e4e 100644..100755
--- a/CPP/7zip/Compress/Bcj2Coder.h
+++ b/CPP/7zip/Compress/Bcj2Coder.h
diff --git a/CPP/7zip/Compress/Bcj2Register.cpp b/CPP/7zip/Compress/Bcj2Register.cpp
index 2868f1c9..2868f1c9 100644..100755
--- a/CPP/7zip/Compress/Bcj2Register.cpp
+++ b/CPP/7zip/Compress/Bcj2Register.cpp
diff --git a/CPP/7zip/Compress/BcjCoder.cpp b/CPP/7zip/Compress/BcjCoder.cpp
index 32aa1762..32aa1762 100644..100755
--- a/CPP/7zip/Compress/BcjCoder.cpp
+++ b/CPP/7zip/Compress/BcjCoder.cpp
diff --git a/CPP/7zip/Compress/BcjCoder.h b/CPP/7zip/Compress/BcjCoder.h
index 7883906e..7883906e 100644..100755
--- a/CPP/7zip/Compress/BcjCoder.h
+++ b/CPP/7zip/Compress/BcjCoder.h
diff --git a/CPP/7zip/Compress/BcjRegister.cpp b/CPP/7zip/Compress/BcjRegister.cpp
index f06dcfe9..f06dcfe9 100644..100755
--- a/CPP/7zip/Compress/BcjRegister.cpp
+++ b/CPP/7zip/Compress/BcjRegister.cpp
diff --git a/CPP/7zip/Compress/BitlDecoder.cpp b/CPP/7zip/Compress/BitlDecoder.cpp
index 876e6497..876e6497 100644..100755
--- a/CPP/7zip/Compress/BitlDecoder.cpp
+++ b/CPP/7zip/Compress/BitlDecoder.cpp
diff --git a/CPP/7zip/Compress/BitlDecoder.h b/CPP/7zip/Compress/BitlDecoder.h
index e85942cf..825864d8 100644..100755
--- a/CPP/7zip/Compress/BitlDecoder.h
+++ b/CPP/7zip/Compress/BitlDecoder.h
@@ -155,6 +155,10 @@ public:
MY_FORCE_INLINE
bool ReadAlignedByte_FromBuf(Byte &b)
{
+ if (this->_stream.NumExtraBytes != 0)
+ if (this->_stream.NumExtraBytes >= 4
+ || kNumBigValueBits - this->_bitPos <= (this->_stream.NumExtraBytes << 3))
+ return false;
if (this->_bitPos == kNumBigValueBits)
return this->_stream.ReadByte_FromBuf(b);
b = (Byte)(_normalValue & 0xFF);
diff --git a/CPP/7zip/Compress/BitlEncoder.h b/CPP/7zip/Compress/BitlEncoder.h
index 9a4612fc..9a4612fc 100644..100755
--- a/CPP/7zip/Compress/BitlEncoder.h
+++ b/CPP/7zip/Compress/BitlEncoder.h
diff --git a/CPP/7zip/Compress/BitmDecoder.h b/CPP/7zip/Compress/BitmDecoder.h
index 9ce41bd1..9ce41bd1 100644..100755
--- a/CPP/7zip/Compress/BitmDecoder.h
+++ b/CPP/7zip/Compress/BitmDecoder.h
diff --git a/CPP/7zip/Compress/BitmEncoder.h b/CPP/7zip/Compress/BitmEncoder.h
index 4499c79d..4499c79d 100644..100755
--- a/CPP/7zip/Compress/BitmEncoder.h
+++ b/CPP/7zip/Compress/BitmEncoder.h
diff --git a/CPP/7zip/Compress/BranchMisc.cpp b/CPP/7zip/Compress/BranchMisc.cpp
index d0e75e83..d0e75e83 100644..100755
--- a/CPP/7zip/Compress/BranchMisc.cpp
+++ b/CPP/7zip/Compress/BranchMisc.cpp
diff --git a/CPP/7zip/Compress/BranchMisc.h b/CPP/7zip/Compress/BranchMisc.h
index 66fc23d2..66fc23d2 100644..100755
--- a/CPP/7zip/Compress/BranchMisc.h
+++ b/CPP/7zip/Compress/BranchMisc.h
diff --git a/CPP/7zip/Compress/BranchRegister.cpp b/CPP/7zip/Compress/BranchRegister.cpp
index 6331c1b9..6331c1b9 100644..100755
--- a/CPP/7zip/Compress/BranchRegister.cpp
+++ b/CPP/7zip/Compress/BranchRegister.cpp
diff --git a/CPP/7zip/Compress/ByteSwap.cpp b/CPP/7zip/Compress/ByteSwap.cpp
index 4c11806e..4c11806e 100644..100755
--- a/CPP/7zip/Compress/ByteSwap.cpp
+++ b/CPP/7zip/Compress/ByteSwap.cpp
diff --git a/CPP/7zip/Compress/Codec.def b/CPP/7zip/Compress/Codec.def
index f55b2d57..f55b2d57 100644..100755
--- a/CPP/7zip/Compress/Codec.def
+++ b/CPP/7zip/Compress/Codec.def
diff --git a/CPP/7zip/Compress/CodecExports.cpp b/CPP/7zip/Compress/CodecExports.cpp
index 5bb6ff8d..5bb6ff8d 100644..100755
--- a/CPP/7zip/Compress/CodecExports.cpp
+++ b/CPP/7zip/Compress/CodecExports.cpp
diff --git a/CPP/7zip/Compress/CopyCoder.cpp b/CPP/7zip/Compress/CopyCoder.cpp
index a49bba8a..a49bba8a 100644..100755
--- a/CPP/7zip/Compress/CopyCoder.cpp
+++ b/CPP/7zip/Compress/CopyCoder.cpp
diff --git a/CPP/7zip/Compress/CopyCoder.h b/CPP/7zip/Compress/CopyCoder.h
index a9d0b6db..a9d0b6db 100644..100755
--- a/CPP/7zip/Compress/CopyCoder.h
+++ b/CPP/7zip/Compress/CopyCoder.h
diff --git a/CPP/7zip/Compress/CopyRegister.cpp b/CPP/7zip/Compress/CopyRegister.cpp
index 7141ab58..7141ab58 100644..100755
--- a/CPP/7zip/Compress/CopyRegister.cpp
+++ b/CPP/7zip/Compress/CopyRegister.cpp
diff --git a/CPP/7zip/Compress/Deflate64Register.cpp b/CPP/7zip/Compress/Deflate64Register.cpp
index 14d20bb3..14d20bb3 100644..100755
--- a/CPP/7zip/Compress/Deflate64Register.cpp
+++ b/CPP/7zip/Compress/Deflate64Register.cpp
diff --git a/CPP/7zip/Compress/DeflateConst.h b/CPP/7zip/Compress/DeflateConst.h
index cfbbf886..cfbbf886 100644..100755
--- a/CPP/7zip/Compress/DeflateConst.h
+++ b/CPP/7zip/Compress/DeflateConst.h
diff --git a/CPP/7zip/Compress/DeflateDecoder.cpp b/CPP/7zip/Compress/DeflateDecoder.cpp
index 0206ce8d..e4f66b7d 100644..100755
--- a/CPP/7zip/Compress/DeflateDecoder.cpp
+++ b/CPP/7zip/Compress/DeflateDecoder.cpp
@@ -426,7 +426,6 @@ STDMETHODIMP CCoder::ReadUnusedFromInBuf(void *data, UInt32 size, UInt32 *proces
{
AlignToByte();
UInt32 i = 0;
- if (!m_InBitStream.ExtraBitsWereRead())
{
for (i = 0; i < size; i++)
{
diff --git a/CPP/7zip/Compress/DeflateDecoder.h b/CPP/7zip/Compress/DeflateDecoder.h
index 141184ef..141184ef 100644..100755
--- a/CPP/7zip/Compress/DeflateDecoder.h
+++ b/CPP/7zip/Compress/DeflateDecoder.h
diff --git a/CPP/7zip/Compress/DeflateEncoder.cpp b/CPP/7zip/Compress/DeflateEncoder.cpp
index 8168ec78..8168ec78 100644..100755
--- a/CPP/7zip/Compress/DeflateEncoder.cpp
+++ b/CPP/7zip/Compress/DeflateEncoder.cpp
diff --git a/CPP/7zip/Compress/DeflateEncoder.h b/CPP/7zip/Compress/DeflateEncoder.h
index 94d250ec..94d250ec 100644..100755
--- a/CPP/7zip/Compress/DeflateEncoder.h
+++ b/CPP/7zip/Compress/DeflateEncoder.h
diff --git a/CPP/7zip/Compress/DeflateRegister.cpp b/CPP/7zip/Compress/DeflateRegister.cpp
index 387be6ed..387be6ed 100644..100755
--- a/CPP/7zip/Compress/DeflateRegister.cpp
+++ b/CPP/7zip/Compress/DeflateRegister.cpp
diff --git a/CPP/7zip/Compress/DeltaFilter.cpp b/CPP/7zip/Compress/DeltaFilter.cpp
index 3986ae4f..3986ae4f 100644..100755
--- a/CPP/7zip/Compress/DeltaFilter.cpp
+++ b/CPP/7zip/Compress/DeltaFilter.cpp
diff --git a/CPP/7zip/Compress/DllExports2Compress.cpp b/CPP/7zip/Compress/DllExports2Compress.cpp
index a6ff6905..a6ff6905 100644..100755
--- a/CPP/7zip/Compress/DllExports2Compress.cpp
+++ b/CPP/7zip/Compress/DllExports2Compress.cpp
diff --git a/CPP/7zip/Compress/DllExportsCompress.cpp b/CPP/7zip/Compress/DllExportsCompress.cpp
index 24749d27..24749d27 100644..100755
--- a/CPP/7zip/Compress/DllExportsCompress.cpp
+++ b/CPP/7zip/Compress/DllExportsCompress.cpp
diff --git a/CPP/7zip/Compress/HuffmanDecoder.h b/CPP/7zip/Compress/HuffmanDecoder.h
index f0529876..f0529876 100644..100755
--- a/CPP/7zip/Compress/HuffmanDecoder.h
+++ b/CPP/7zip/Compress/HuffmanDecoder.h
diff --git a/CPP/7zip/Compress/ImplodeDecoder.cpp b/CPP/7zip/Compress/ImplodeDecoder.cpp
index 97a3cdf7..97a3cdf7 100644..100755
--- a/CPP/7zip/Compress/ImplodeDecoder.cpp
+++ b/CPP/7zip/Compress/ImplodeDecoder.cpp
diff --git a/CPP/7zip/Compress/ImplodeDecoder.h b/CPP/7zip/Compress/ImplodeDecoder.h
index a73c143c..a73c143c 100644..100755
--- a/CPP/7zip/Compress/ImplodeDecoder.h
+++ b/CPP/7zip/Compress/ImplodeDecoder.h
diff --git a/CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp b/CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp
index 7d31bb94..7d31bb94 100644..100755
--- a/CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp
+++ b/CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp
diff --git a/CPP/7zip/Compress/ImplodeHuffmanDecoder.h b/CPP/7zip/Compress/ImplodeHuffmanDecoder.h
index ea25211a..ea25211a 100644..100755
--- a/CPP/7zip/Compress/ImplodeHuffmanDecoder.h
+++ b/CPP/7zip/Compress/ImplodeHuffmanDecoder.h
diff --git a/CPP/7zip/Compress/LzOutWindow.cpp b/CPP/7zip/Compress/LzOutWindow.cpp
index eb346407..eb346407 100644..100755
--- a/CPP/7zip/Compress/LzOutWindow.cpp
+++ b/CPP/7zip/Compress/LzOutWindow.cpp
diff --git a/CPP/7zip/Compress/LzOutWindow.h b/CPP/7zip/Compress/LzOutWindow.h
index 30ac334f..30ac334f 100644..100755
--- a/CPP/7zip/Compress/LzOutWindow.h
+++ b/CPP/7zip/Compress/LzOutWindow.h
diff --git a/CPP/7zip/Compress/LzfseDecoder.cpp b/CPP/7zip/Compress/LzfseDecoder.cpp
index 41c7445a..41c7445a 100644..100755
--- a/CPP/7zip/Compress/LzfseDecoder.cpp
+++ b/CPP/7zip/Compress/LzfseDecoder.cpp
diff --git a/CPP/7zip/Compress/LzfseDecoder.h b/CPP/7zip/Compress/LzfseDecoder.h
index 0156a087..0156a087 100644..100755
--- a/CPP/7zip/Compress/LzfseDecoder.h
+++ b/CPP/7zip/Compress/LzfseDecoder.h
diff --git a/CPP/7zip/Compress/LzhDecoder.cpp b/CPP/7zip/Compress/LzhDecoder.cpp
index b0aa7536..b0aa7536 100644..100755
--- a/CPP/7zip/Compress/LzhDecoder.cpp
+++ b/CPP/7zip/Compress/LzhDecoder.cpp
diff --git a/CPP/7zip/Compress/LzhDecoder.h b/CPP/7zip/Compress/LzhDecoder.h
index 5e13d823..5e13d823 100644..100755
--- a/CPP/7zip/Compress/LzhDecoder.h
+++ b/CPP/7zip/Compress/LzhDecoder.h
diff --git a/CPP/7zip/Compress/Lzma2Decoder.cpp b/CPP/7zip/Compress/Lzma2Decoder.cpp
index 653fe2de..653fe2de 100644..100755
--- a/CPP/7zip/Compress/Lzma2Decoder.cpp
+++ b/CPP/7zip/Compress/Lzma2Decoder.cpp
diff --git a/CPP/7zip/Compress/Lzma2Decoder.h b/CPP/7zip/Compress/Lzma2Decoder.h
index e1414884..e1414884 100644..100755
--- a/CPP/7zip/Compress/Lzma2Decoder.h
+++ b/CPP/7zip/Compress/Lzma2Decoder.h
diff --git a/CPP/7zip/Compress/Lzma2Encoder.cpp b/CPP/7zip/Compress/Lzma2Encoder.cpp
index 6a5d6797..6a5d6797 100644..100755
--- a/CPP/7zip/Compress/Lzma2Encoder.cpp
+++ b/CPP/7zip/Compress/Lzma2Encoder.cpp
diff --git a/CPP/7zip/Compress/Lzma2Encoder.h b/CPP/7zip/Compress/Lzma2Encoder.h
index f681ad16..f681ad16 100644..100755
--- a/CPP/7zip/Compress/Lzma2Encoder.h
+++ b/CPP/7zip/Compress/Lzma2Encoder.h
diff --git a/CPP/7zip/Compress/Lzma2Register.cpp b/CPP/7zip/Compress/Lzma2Register.cpp
index 8f279ebf..8f279ebf 100644..100755
--- a/CPP/7zip/Compress/Lzma2Register.cpp
+++ b/CPP/7zip/Compress/Lzma2Register.cpp
diff --git a/CPP/7zip/Compress/LzmaDecoder.cpp b/CPP/7zip/Compress/LzmaDecoder.cpp
index a25d36d1..a25d36d1 100644..100755
--- a/CPP/7zip/Compress/LzmaDecoder.cpp
+++ b/CPP/7zip/Compress/LzmaDecoder.cpp
diff --git a/CPP/7zip/Compress/LzmaDecoder.h b/CPP/7zip/Compress/LzmaDecoder.h
index 37dec025..37dec025 100644..100755
--- a/CPP/7zip/Compress/LzmaDecoder.h
+++ b/CPP/7zip/Compress/LzmaDecoder.h
diff --git a/CPP/7zip/Compress/LzmaEncoder.cpp b/CPP/7zip/Compress/LzmaEncoder.cpp
index 4b3acd30..dabd77a0 100644..100755
--- a/CPP/7zip/Compress/LzmaEncoder.cpp
+++ b/CPP/7zip/Compress/LzmaEncoder.cpp
@@ -9,14 +9,15 @@
#include "LzmaEncoder.h"
-#include "../../Common/IntToString.h"
-#include "../../Windows/TimeUtils.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
diff --git a/CPP/7zip/Compress/LzmaEncoder.h b/CPP/7zip/Compress/LzmaEncoder.h
index 7d706ad7..7d706ad7 100644..100755
--- a/CPP/7zip/Compress/LzmaEncoder.h
+++ b/CPP/7zip/Compress/LzmaEncoder.h
diff --git a/CPP/7zip/Compress/LzmaRegister.cpp b/CPP/7zip/Compress/LzmaRegister.cpp
index c802a99f..c802a99f 100644..100755
--- a/CPP/7zip/Compress/LzmaRegister.cpp
+++ b/CPP/7zip/Compress/LzmaRegister.cpp
diff --git a/CPP/7zip/Compress/LzmsDecoder.cpp b/CPP/7zip/Compress/LzmsDecoder.cpp
index e27afa3c..e27afa3c 100644..100755
--- a/CPP/7zip/Compress/LzmsDecoder.cpp
+++ b/CPP/7zip/Compress/LzmsDecoder.cpp
diff --git a/CPP/7zip/Compress/LzmsDecoder.h b/CPP/7zip/Compress/LzmsDecoder.h
index f0909a1e..f0909a1e 100644..100755
--- a/CPP/7zip/Compress/LzmsDecoder.h
+++ b/CPP/7zip/Compress/LzmsDecoder.h
diff --git a/CPP/7zip/Compress/Lzx.h b/CPP/7zip/Compress/Lzx.h
index 29ca4cac..29ca4cac 100644..100755
--- a/CPP/7zip/Compress/Lzx.h
+++ b/CPP/7zip/Compress/Lzx.h
diff --git a/CPP/7zip/Compress/LzxDecoder.cpp b/CPP/7zip/Compress/LzxDecoder.cpp
index e59cd400..e59cd400 100644..100755
--- a/CPP/7zip/Compress/LzxDecoder.cpp
+++ b/CPP/7zip/Compress/LzxDecoder.cpp
diff --git a/CPP/7zip/Compress/LzxDecoder.h b/CPP/7zip/Compress/LzxDecoder.h
index 4d70b272..4d70b272 100644..100755
--- a/CPP/7zip/Compress/LzxDecoder.h
+++ b/CPP/7zip/Compress/LzxDecoder.h
diff --git a/CPP/7zip/Compress/Mtf8.h b/CPP/7zip/Compress/Mtf8.h
index 50a84cee..50a84cee 100644..100755
--- a/CPP/7zip/Compress/Mtf8.h
+++ b/CPP/7zip/Compress/Mtf8.h
diff --git a/CPP/7zip/Compress/PpmdDecoder.cpp b/CPP/7zip/Compress/PpmdDecoder.cpp
index 7f54ec3b..7f54ec3b 100644..100755
--- a/CPP/7zip/Compress/PpmdDecoder.cpp
+++ b/CPP/7zip/Compress/PpmdDecoder.cpp
diff --git a/CPP/7zip/Compress/PpmdDecoder.h b/CPP/7zip/Compress/PpmdDecoder.h
index f1a8ee21..f1a8ee21 100644..100755
--- a/CPP/7zip/Compress/PpmdDecoder.h
+++ b/CPP/7zip/Compress/PpmdDecoder.h
diff --git a/CPP/7zip/Compress/PpmdEncoder.cpp b/CPP/7zip/Compress/PpmdEncoder.cpp
index d41d2aca..d41d2aca 100644..100755
--- a/CPP/7zip/Compress/PpmdEncoder.cpp
+++ b/CPP/7zip/Compress/PpmdEncoder.cpp
diff --git a/CPP/7zip/Compress/PpmdEncoder.h b/CPP/7zip/Compress/PpmdEncoder.h
index 0104663f..0104663f 100644..100755
--- a/CPP/7zip/Compress/PpmdEncoder.h
+++ b/CPP/7zip/Compress/PpmdEncoder.h
diff --git a/CPP/7zip/Compress/PpmdRegister.cpp b/CPP/7zip/Compress/PpmdRegister.cpp
index a3ebb5f3..a3ebb5f3 100644..100755
--- a/CPP/7zip/Compress/PpmdRegister.cpp
+++ b/CPP/7zip/Compress/PpmdRegister.cpp
diff --git a/CPP/7zip/Compress/PpmdZip.cpp b/CPP/7zip/Compress/PpmdZip.cpp
index 434e143b..434e143b 100644..100755
--- a/CPP/7zip/Compress/PpmdZip.cpp
+++ b/CPP/7zip/Compress/PpmdZip.cpp
diff --git a/CPP/7zip/Compress/PpmdZip.h b/CPP/7zip/Compress/PpmdZip.h
index 9d1fc4bd..9d1fc4bd 100644..100755
--- a/CPP/7zip/Compress/PpmdZip.h
+++ b/CPP/7zip/Compress/PpmdZip.h
diff --git a/CPP/7zip/Compress/QuantumDecoder.cpp b/CPP/7zip/Compress/QuantumDecoder.cpp
index 8c650581..8c650581 100644..100755
--- a/CPP/7zip/Compress/QuantumDecoder.cpp
+++ b/CPP/7zip/Compress/QuantumDecoder.cpp
diff --git a/CPP/7zip/Compress/QuantumDecoder.h b/CPP/7zip/Compress/QuantumDecoder.h
index afeba708..afeba708 100644..100755
--- a/CPP/7zip/Compress/QuantumDecoder.h
+++ b/CPP/7zip/Compress/QuantumDecoder.h
diff --git a/CPP/7zip/Compress/Rar1Decoder.cpp b/CPP/7zip/Compress/Rar1Decoder.cpp
index 510bbd17..510bbd17 100644..100755
--- a/CPP/7zip/Compress/Rar1Decoder.cpp
+++ b/CPP/7zip/Compress/Rar1Decoder.cpp
diff --git a/CPP/7zip/Compress/Rar1Decoder.h b/CPP/7zip/Compress/Rar1Decoder.h
index 52907e5c..52907e5c 100644..100755
--- a/CPP/7zip/Compress/Rar1Decoder.h
+++ b/CPP/7zip/Compress/Rar1Decoder.h
diff --git a/CPP/7zip/Compress/Rar2Decoder.cpp b/CPP/7zip/Compress/Rar2Decoder.cpp
index b1c8c2d4..b1c8c2d4 100644..100755
--- a/CPP/7zip/Compress/Rar2Decoder.cpp
+++ b/CPP/7zip/Compress/Rar2Decoder.cpp
diff --git a/CPP/7zip/Compress/Rar2Decoder.h b/CPP/7zip/Compress/Rar2Decoder.h
index f42f228d..f42f228d 100644..100755
--- a/CPP/7zip/Compress/Rar2Decoder.h
+++ b/CPP/7zip/Compress/Rar2Decoder.h
diff --git a/CPP/7zip/Compress/Rar3Decoder.cpp b/CPP/7zip/Compress/Rar3Decoder.cpp
index 2271dcc8..2271dcc8 100644..100755
--- a/CPP/7zip/Compress/Rar3Decoder.cpp
+++ b/CPP/7zip/Compress/Rar3Decoder.cpp
diff --git a/CPP/7zip/Compress/Rar3Decoder.h b/CPP/7zip/Compress/Rar3Decoder.h
index fdecc55f..fdecc55f 100644..100755
--- a/CPP/7zip/Compress/Rar3Decoder.h
+++ b/CPP/7zip/Compress/Rar3Decoder.h
diff --git a/CPP/7zip/Compress/Rar3Vm.cpp b/CPP/7zip/Compress/Rar3Vm.cpp
index 6accd08c..6accd08c 100644..100755
--- a/CPP/7zip/Compress/Rar3Vm.cpp
+++ b/CPP/7zip/Compress/Rar3Vm.cpp
diff --git a/CPP/7zip/Compress/Rar3Vm.h b/CPP/7zip/Compress/Rar3Vm.h
index 3fc51510..3fc51510 100644..100755
--- a/CPP/7zip/Compress/Rar3Vm.h
+++ b/CPP/7zip/Compress/Rar3Vm.h
diff --git a/CPP/7zip/Compress/Rar5Decoder.cpp b/CPP/7zip/Compress/Rar5Decoder.cpp
index caabb316..caabb316 100644..100755
--- a/CPP/7zip/Compress/Rar5Decoder.cpp
+++ b/CPP/7zip/Compress/Rar5Decoder.cpp
diff --git a/CPP/7zip/Compress/Rar5Decoder.h b/CPP/7zip/Compress/Rar5Decoder.h
index 8174c4af..8174c4af 100644..100755
--- a/CPP/7zip/Compress/Rar5Decoder.h
+++ b/CPP/7zip/Compress/Rar5Decoder.h
diff --git a/CPP/7zip/Compress/RarCodecsRegister.cpp b/CPP/7zip/Compress/RarCodecsRegister.cpp
index e1bc3d9b..e1bc3d9b 100644..100755
--- a/CPP/7zip/Compress/RarCodecsRegister.cpp
+++ b/CPP/7zip/Compress/RarCodecsRegister.cpp
diff --git a/CPP/7zip/Compress/ShrinkDecoder.cpp b/CPP/7zip/Compress/ShrinkDecoder.cpp
index 22f3844c..22f3844c 100644..100755
--- a/CPP/7zip/Compress/ShrinkDecoder.cpp
+++ b/CPP/7zip/Compress/ShrinkDecoder.cpp
diff --git a/CPP/7zip/Compress/ShrinkDecoder.h b/CPP/7zip/Compress/ShrinkDecoder.h
index b095b5f4..b095b5f4 100644..100755
--- a/CPP/7zip/Compress/ShrinkDecoder.h
+++ b/CPP/7zip/Compress/ShrinkDecoder.h
diff --git a/CPP/7zip/Compress/StdAfx.h b/CPP/7zip/Compress/StdAfx.h
index 1cbd7fea..1cbd7fea 100644..100755
--- a/CPP/7zip/Compress/StdAfx.h
+++ b/CPP/7zip/Compress/StdAfx.h
diff --git a/CPP/7zip/Compress/XpressDecoder.cpp b/CPP/7zip/Compress/XpressDecoder.cpp
index a8bbd008..a8bbd008 100644..100755
--- a/CPP/7zip/Compress/XpressDecoder.cpp
+++ b/CPP/7zip/Compress/XpressDecoder.cpp
diff --git a/CPP/7zip/Compress/XpressDecoder.h b/CPP/7zip/Compress/XpressDecoder.h
index cada85bf..cada85bf 100644..100755
--- a/CPP/7zip/Compress/XpressDecoder.h
+++ b/CPP/7zip/Compress/XpressDecoder.h
diff --git a/CPP/7zip/Compress/XzDecoder.cpp b/CPP/7zip/Compress/XzDecoder.cpp
index 0371173c..0371173c 100644..100755
--- a/CPP/7zip/Compress/XzDecoder.cpp
+++ b/CPP/7zip/Compress/XzDecoder.cpp
diff --git a/CPP/7zip/Compress/XzDecoder.h b/CPP/7zip/Compress/XzDecoder.h
index 7ad81f49..7ad81f49 100644..100755
--- a/CPP/7zip/Compress/XzDecoder.h
+++ b/CPP/7zip/Compress/XzDecoder.h
diff --git a/CPP/7zip/Compress/XzEncoder.cpp b/CPP/7zip/Compress/XzEncoder.cpp
index d6f42caf..d6f42caf 100644..100755
--- a/CPP/7zip/Compress/XzEncoder.cpp
+++ b/CPP/7zip/Compress/XzEncoder.cpp
diff --git a/CPP/7zip/Compress/XzEncoder.h b/CPP/7zip/Compress/XzEncoder.h
index ea5190ee..ea5190ee 100644..100755
--- a/CPP/7zip/Compress/XzEncoder.h
+++ b/CPP/7zip/Compress/XzEncoder.h
diff --git a/CPP/7zip/Compress/ZDecoder.cpp b/CPP/7zip/Compress/ZDecoder.cpp
index 06eab00e..06eab00e 100644..100755
--- a/CPP/7zip/Compress/ZDecoder.cpp
+++ b/CPP/7zip/Compress/ZDecoder.cpp
diff --git a/CPP/7zip/Compress/ZDecoder.h b/CPP/7zip/Compress/ZDecoder.h
index 19acd498..19acd498 100644..100755
--- a/CPP/7zip/Compress/ZDecoder.h
+++ b/CPP/7zip/Compress/ZDecoder.h
diff --git a/CPP/7zip/Compress/ZlibDecoder.cpp b/CPP/7zip/Compress/ZlibDecoder.cpp
index 2356c7c5..2356c7c5 100644..100755
--- a/CPP/7zip/Compress/ZlibDecoder.cpp
+++ b/CPP/7zip/Compress/ZlibDecoder.cpp
diff --git a/CPP/7zip/Compress/ZlibDecoder.h b/CPP/7zip/Compress/ZlibDecoder.h
index 8c5e73b0..8c5e73b0 100644..100755
--- a/CPP/7zip/Compress/ZlibDecoder.h
+++ b/CPP/7zip/Compress/ZlibDecoder.h
diff --git a/CPP/7zip/Compress/ZlibEncoder.cpp b/CPP/7zip/Compress/ZlibEncoder.cpp
index 09235c33..09235c33 100644..100755
--- a/CPP/7zip/Compress/ZlibEncoder.cpp
+++ b/CPP/7zip/Compress/ZlibEncoder.cpp
diff --git a/CPP/7zip/Compress/ZlibEncoder.h b/CPP/7zip/Compress/ZlibEncoder.h
index 621cc1d0..621cc1d0 100644..100755
--- a/CPP/7zip/Compress/ZlibEncoder.h
+++ b/CPP/7zip/Compress/ZlibEncoder.h
diff --git a/CPP/7zip/Compress/makefile b/CPP/7zip/Compress/makefile
index e981319d..e981319d 100644..100755
--- a/CPP/7zip/Compress/makefile
+++ b/CPP/7zip/Compress/makefile
diff --git a/CPP/7zip/Crc.mak b/CPP/7zip/Crc.mak
index 815142db..815142db 100644..100755
--- a/CPP/7zip/Crc.mak
+++ b/CPP/7zip/Crc.mak
diff --git a/CPP/7zip/Crc64.mak b/CPP/7zip/Crc64.mak
index d58a4832..d58a4832 100644..100755
--- a/CPP/7zip/Crc64.mak
+++ b/CPP/7zip/Crc64.mak
diff --git a/CPP/7zip/Crypto/7zAes.cpp b/CPP/7zip/Crypto/7zAes.cpp
index 7f34e910..7f34e910 100644..100755
--- a/CPP/7zip/Crypto/7zAes.cpp
+++ b/CPP/7zip/Crypto/7zAes.cpp
diff --git a/CPP/7zip/Crypto/7zAes.h b/CPP/7zip/Crypto/7zAes.h
index a67ac0b6..a67ac0b6 100644..100755
--- a/CPP/7zip/Crypto/7zAes.h
+++ b/CPP/7zip/Crypto/7zAes.h
diff --git a/CPP/7zip/Crypto/7zAesRegister.cpp b/CPP/7zip/Crypto/7zAesRegister.cpp
index 35605f43..35605f43 100644..100755
--- a/CPP/7zip/Crypto/7zAesRegister.cpp
+++ b/CPP/7zip/Crypto/7zAesRegister.cpp
diff --git a/CPP/7zip/Crypto/Codec.def b/CPP/7zip/Crypto/Codec.def
index ebf73a3b..ebf73a3b 100644..100755
--- a/CPP/7zip/Crypto/Codec.def
+++ b/CPP/7zip/Crypto/Codec.def
diff --git a/CPP/7zip/Crypto/HmacSha1.cpp b/CPP/7zip/Crypto/HmacSha1.cpp
index d085bb05..d085bb05 100644..100755
--- a/CPP/7zip/Crypto/HmacSha1.cpp
+++ b/CPP/7zip/Crypto/HmacSha1.cpp
diff --git a/CPP/7zip/Crypto/HmacSha1.h b/CPP/7zip/Crypto/HmacSha1.h
index d4b21b36..d4b21b36 100644..100755
--- a/CPP/7zip/Crypto/HmacSha1.h
+++ b/CPP/7zip/Crypto/HmacSha1.h
diff --git a/CPP/7zip/Crypto/HmacSha256.cpp b/CPP/7zip/Crypto/HmacSha256.cpp
index cec5e752..cec5e752 100644..100755
--- a/CPP/7zip/Crypto/HmacSha256.cpp
+++ b/CPP/7zip/Crypto/HmacSha256.cpp
diff --git a/CPP/7zip/Crypto/HmacSha256.h b/CPP/7zip/Crypto/HmacSha256.h
index d709f43d..d709f43d 100644..100755
--- a/CPP/7zip/Crypto/HmacSha256.h
+++ b/CPP/7zip/Crypto/HmacSha256.h
diff --git a/CPP/7zip/Crypto/MyAes.cpp b/CPP/7zip/Crypto/MyAes.cpp
index 5cb7f463..5cb7f463 100644..100755
--- a/CPP/7zip/Crypto/MyAes.cpp
+++ b/CPP/7zip/Crypto/MyAes.cpp
diff --git a/CPP/7zip/Crypto/MyAes.h b/CPP/7zip/Crypto/MyAes.h
index a60042be..a60042be 100644..100755
--- a/CPP/7zip/Crypto/MyAes.h
+++ b/CPP/7zip/Crypto/MyAes.h
diff --git a/CPP/7zip/Crypto/MyAesReg.cpp b/CPP/7zip/Crypto/MyAesReg.cpp
index 86bd2547..86bd2547 100644..100755
--- a/CPP/7zip/Crypto/MyAesReg.cpp
+++ b/CPP/7zip/Crypto/MyAesReg.cpp
diff --git a/CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp b/CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp
index 6b504ee9..6b504ee9 100644..100755
--- a/CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp
+++ b/CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp
diff --git a/CPP/7zip/Crypto/Pbkdf2HmacSha1.h b/CPP/7zip/Crypto/Pbkdf2HmacSha1.h
index e9462e47..e9462e47 100644..100755
--- a/CPP/7zip/Crypto/Pbkdf2HmacSha1.h
+++ b/CPP/7zip/Crypto/Pbkdf2HmacSha1.h
diff --git a/CPP/7zip/Crypto/RandGen.cpp b/CPP/7zip/Crypto/RandGen.cpp
index 65633fd8..65633fd8 100644..100755
--- a/CPP/7zip/Crypto/RandGen.cpp
+++ b/CPP/7zip/Crypto/RandGen.cpp
diff --git a/CPP/7zip/Crypto/RandGen.h b/CPP/7zip/Crypto/RandGen.h
index 5122ec4b..5122ec4b 100644..100755
--- a/CPP/7zip/Crypto/RandGen.h
+++ b/CPP/7zip/Crypto/RandGen.h
diff --git a/CPP/7zip/Crypto/Rar20Crypto.cpp b/CPP/7zip/Crypto/Rar20Crypto.cpp
index 2bbaa931..2bbaa931 100644..100755
--- a/CPP/7zip/Crypto/Rar20Crypto.cpp
+++ b/CPP/7zip/Crypto/Rar20Crypto.cpp
diff --git a/CPP/7zip/Crypto/Rar20Crypto.h b/CPP/7zip/Crypto/Rar20Crypto.h
index 596619ce..596619ce 100644..100755
--- a/CPP/7zip/Crypto/Rar20Crypto.h
+++ b/CPP/7zip/Crypto/Rar20Crypto.h
diff --git a/CPP/7zip/Crypto/Rar5Aes.cpp b/CPP/7zip/Crypto/Rar5Aes.cpp
index 5834bbb7..5834bbb7 100644..100755
--- a/CPP/7zip/Crypto/Rar5Aes.cpp
+++ b/CPP/7zip/Crypto/Rar5Aes.cpp
diff --git a/CPP/7zip/Crypto/Rar5Aes.h b/CPP/7zip/Crypto/Rar5Aes.h
index e779c17b..e779c17b 100644..100755
--- a/CPP/7zip/Crypto/Rar5Aes.h
+++ b/CPP/7zip/Crypto/Rar5Aes.h
diff --git a/CPP/7zip/Crypto/RarAes.cpp b/CPP/7zip/Crypto/RarAes.cpp
index aa9444cf..aa9444cf 100644..100755
--- a/CPP/7zip/Crypto/RarAes.cpp
+++ b/CPP/7zip/Crypto/RarAes.cpp
diff --git a/CPP/7zip/Crypto/RarAes.h b/CPP/7zip/Crypto/RarAes.h
index 2bb68667..2bb68667 100644..100755
--- a/CPP/7zip/Crypto/RarAes.h
+++ b/CPP/7zip/Crypto/RarAes.h
diff --git a/CPP/7zip/Crypto/Sha1Cls.h b/CPP/7zip/Crypto/Sha1Cls.h
index 34616782..34616782 100644..100755
--- a/CPP/7zip/Crypto/Sha1Cls.h
+++ b/CPP/7zip/Crypto/Sha1Cls.h
diff --git a/CPP/7zip/Crypto/StdAfx.h b/CPP/7zip/Crypto/StdAfx.h
index 1cbd7fea..1cbd7fea 100644..100755
--- a/CPP/7zip/Crypto/StdAfx.h
+++ b/CPP/7zip/Crypto/StdAfx.h
diff --git a/CPP/7zip/Crypto/WzAes.cpp b/CPP/7zip/Crypto/WzAes.cpp
index b422b501..b422b501 100644..100755
--- a/CPP/7zip/Crypto/WzAes.cpp
+++ b/CPP/7zip/Crypto/WzAes.cpp
diff --git a/CPP/7zip/Crypto/WzAes.h b/CPP/7zip/Crypto/WzAes.h
index fa6221c5..fa6221c5 100644..100755
--- a/CPP/7zip/Crypto/WzAes.h
+++ b/CPP/7zip/Crypto/WzAes.h
diff --git a/CPP/7zip/Crypto/ZipCrypto.cpp b/CPP/7zip/Crypto/ZipCrypto.cpp
index 8610297a..8610297a 100644..100755
--- a/CPP/7zip/Crypto/ZipCrypto.cpp
+++ b/CPP/7zip/Crypto/ZipCrypto.cpp
diff --git a/CPP/7zip/Crypto/ZipCrypto.h b/CPP/7zip/Crypto/ZipCrypto.h
index d2fe4c4f..d2fe4c4f 100644..100755
--- a/CPP/7zip/Crypto/ZipCrypto.h
+++ b/CPP/7zip/Crypto/ZipCrypto.h
diff --git a/CPP/7zip/Crypto/ZipStrong.cpp b/CPP/7zip/Crypto/ZipStrong.cpp
index 895ce949..895ce949 100644..100755
--- a/CPP/7zip/Crypto/ZipStrong.cpp
+++ b/CPP/7zip/Crypto/ZipStrong.cpp
diff --git a/CPP/7zip/Crypto/ZipStrong.h b/CPP/7zip/Crypto/ZipStrong.h
index 2b58a5cb..2b58a5cb 100644..100755
--- a/CPP/7zip/Crypto/ZipStrong.h
+++ b/CPP/7zip/Crypto/ZipStrong.h
diff --git a/CPP/7zip/GuiCommon.rc b/CPP/7zip/GuiCommon.rc
index b67409b9..b67409b9 100644..100755
--- a/CPP/7zip/GuiCommon.rc
+++ b/CPP/7zip/GuiCommon.rc
diff --git a/CPP/7zip/Guid.txt b/CPP/7zip/Guid.txt
index 3b654bc8..8fcdd849 100644..100755
--- a/CPP/7zip/Guid.txt
+++ b/CPP/7zip/Guid.txt
@@ -19,6 +19,7 @@
0F IOutFolderArchive
10 IFolderArchiveUpdateCallback2
11 IFolderScanProgress
+ 12 IFolderSetZoneIdMode
20 IFileExtractCallback.h::IGetProp
30 IFileExtractCallback.h::IFolderExtractToStreamCallback (old)
@@ -34,6 +35,7 @@
07 IOutStreamFinish
08 IStreamGetProps
09 IStreamGetProps2
+ 0A IStreamGetProp
04 ICoder.h
@@ -106,6 +108,8 @@
82 IArchiveUpdateCallback2
83 IArchiveUpdateCallbackFile
84 IArchiveGetDiskProperty
+ 85 IArchiveUpdateCallbackArcProp (Reserved)
+
A0 IOutArchive
@@ -169,6 +173,10 @@ Handler GUIDs:
0C xz
0D ppmd
+ C0 AVB
+ C1 LP
+ C2 Sparse
+ C3 APFS
C4 Vhdx
C5 Base64
C6 COFF
diff --git a/CPP/7zip/ICoder.h b/CPP/7zip/ICoder.h
index 9177f5e5..9177f5e5 100644..100755
--- a/CPP/7zip/ICoder.h
+++ b/CPP/7zip/ICoder.h
diff --git a/CPP/7zip/IDecl.h b/CPP/7zip/IDecl.h
index 077ef0ee..077ef0ee 100644..100755
--- a/CPP/7zip/IDecl.h
+++ b/CPP/7zip/IDecl.h
diff --git a/CPP/7zip/IPassword.h b/CPP/7zip/IPassword.h
index 4ccc9ac7..4ccc9ac7 100644..100755
--- a/CPP/7zip/IPassword.h
+++ b/CPP/7zip/IPassword.h
diff --git a/CPP/7zip/IProgress.h b/CPP/7zip/IProgress.h
index fac951ec..fac951ec 100644..100755
--- a/CPP/7zip/IProgress.h
+++ b/CPP/7zip/IProgress.h
diff --git a/CPP/7zip/IStream.h b/CPP/7zip/IStream.h
index 48c67c1a..2793a1e9 100644..100755
--- a/CPP/7zip/IStream.h
+++ b/CPP/7zip/IStream.h
@@ -133,4 +133,11 @@ STREAM_INTERFACE(IStreamGetProps2, 0x09)
STDMETHOD(GetProps2)(CStreamFileProps *props) PURE;
};
+
+STREAM_INTERFACE(IStreamGetProp, 0x0a)
+{
+ STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value) PURE;
+ STDMETHOD(ReloadProps)() PURE;
+};
+
#endif
diff --git a/CPP/7zip/LzFindOpt.mak b/CPP/7zip/LzFindOpt.mak
index 169e10f0..169e10f0 100644..100755
--- a/CPP/7zip/LzFindOpt.mak
+++ b/CPP/7zip/LzFindOpt.mak
diff --git a/CPP/7zip/LzmaDec.mak b/CPP/7zip/LzmaDec.mak
index bed4700a..bed4700a 100644..100755
--- a/CPP/7zip/LzmaDec.mak
+++ b/CPP/7zip/LzmaDec.mak
diff --git a/CPP/7zip/LzmaDec_gcc.mak b/CPP/7zip/LzmaDec_gcc.mak
index 51924f50..51924f50 100644..100755
--- a/CPP/7zip/LzmaDec_gcc.mak
+++ b/CPP/7zip/LzmaDec_gcc.mak
diff --git a/CPP/7zip/MyVersion.h b/CPP/7zip/MyVersion.h
index 8f52a126..8f52a126 100644..100755
--- a/CPP/7zip/MyVersion.h
+++ b/CPP/7zip/MyVersion.h
diff --git a/CPP/7zip/MyVersionInfo.rc b/CPP/7zip/MyVersionInfo.rc
index fab66860..fab66860 100644..100755
--- a/CPP/7zip/MyVersionInfo.rc
+++ b/CPP/7zip/MyVersionInfo.rc
diff --git a/CPP/7zip/PropID.h b/CPP/7zip/PropID.h
index b818954f..2da636fa 100644..100755
--- a/CPP/7zip/PropID.h
+++ b/CPP/7zip/PropID.h
@@ -105,7 +105,11 @@ enum
kpidCopyLink,
kpidArcFileName,
kpidIsHash,
-
+ kpidChangeTime,
+ kpidUserId,
+ kpidGroupId,
+ kpidDeviceMajor,
+ kpidDeviceMinor,
kpid_NUM_DEFINED,
@@ -127,4 +131,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/CPP/7zip/Sha1.mak b/CPP/7zip/Sha1.mak
index 1b5f605f..1b5f605f 100644..100755
--- a/CPP/7zip/Sha1.mak
+++ b/CPP/7zip/Sha1.mak
diff --git a/CPP/7zip/Sha256.mak b/CPP/7zip/Sha256.mak
index 0bdbcb60..0bdbcb60 100644..100755
--- a/CPP/7zip/Sha256.mak
+++ b/CPP/7zip/Sha256.mak
diff --git a/CPP/7zip/SubBuild.mak b/CPP/7zip/SubBuild.mak
index f86ce436..f86ce436 100644..100755
--- a/CPP/7zip/SubBuild.mak
+++ b/CPP/7zip/SubBuild.mak
diff --git a/CPP/7zip/UI/Agent/Agent.cpp b/CPP/7zip/UI/Agent/Agent.cpp
index cdb0e5d1..cc20c116 100644..100755
--- a/CPP/7zip/UI/Agent/Agent.cpp
+++ b/CPP/7zip/UI/Agent/Agent.cpp
@@ -25,6 +25,10 @@ using namespace NWindows;
CCodecs *g_CodecsObj;
+static const bool k_keepEmptyDirPrefixes =
+ false; // 22.00
+ // true; // 21.07
+
#ifdef EXTERNAL_CODECS
CExternalCodecs g_ExternalCodecs;
const CExternalCodecs *g_ExternalCodecs_Ptr;
@@ -114,9 +118,9 @@ void CAgentFolder::LoadFolder(unsigned proxyDirIndex)
item.Index = i;
_items.Add(item);
const CProxyFile2 &file = _proxy2->Files[dir.Items[i]];
- if (file.DirIndex >= 0)
+ if (file.DirIndex != -1)
LoadFolder(file.DirIndex);
- if (_loadAltStreams && file.AltDirIndex >= 0)
+ if (_loadAltStreams && file.AltDirIndex != -1)
LoadFolder(file.AltDirIndex);
}
return;
@@ -211,21 +215,21 @@ void CAgentFolder::GetPrefix(UInt32 index, UString &prefix) const
unsigned len = 0;
while (proxyIndex != _proxyDirIndex && proxyIndex >= k_Proxy2_NumRootDirs)
{
- const CProxyFile2 &file = _proxy2->Files[_proxy2->Dirs[proxyIndex].ArcIndex];
+ const CProxyFile2 &file = _proxy2->Files[(unsigned)_proxy2->Dirs[proxyIndex].ArcIndex];
len += file.NameLen + 1;
- proxyIndex = (file.Parent < 0) ? 0 : _proxy2->Files[file.Parent].GetDirIndex(file.IsAltStream);
+ proxyIndex = (file.Parent == -1) ? 0 : _proxy2->Files[(unsigned)file.Parent].GetDirIndex(file.IsAltStream);
}
wchar_t *p = prefix.GetBuf_SetEnd(len) + len;
proxyIndex = item.DirIndex;
while (proxyIndex != _proxyDirIndex && proxyIndex >= k_Proxy2_NumRootDirs)
{
- const CProxyFile2 &file = _proxy2->Files[_proxy2->Dirs[proxyIndex].ArcIndex];
+ const CProxyFile2 &file = _proxy2->Files[(unsigned)_proxy2->Dirs[proxyIndex].ArcIndex];
p--;
*p = WCHAR_PATH_SEPARATOR;
p -= file.NameLen;
wmemcpy(p, file.Name, file.NameLen);
- proxyIndex = (file.Parent < 0) ? 0 : _proxy2->Files[file.Parent].GetDirIndex(file.IsAltStream);
+ proxyIndex = (file.Parent == -1) ? 0 : _proxy2->Files[(unsigned)file.Parent].GetDirIndex(file.IsAltStream);
}
}
else
@@ -327,7 +331,7 @@ STDMETHODIMP CAgentFolder::GetProperty(UInt32 index, PROPID propID, PROPVARIANT
/*
if (propID == kpidNumAltStreams)
{
- if (item.AltDirIndex >= 0)
+ if (item.AltDirIndex != -1)
prop = _proxy2->Dirs[item.AltDirIndex].Items.Size();
}
else
@@ -887,12 +891,12 @@ STDMETHODIMP CAgentFolder::BindToFolder(const wchar_t *name, IFolderFolder **res
if (_proxy2)
{
int index = _proxy2->FindItem(_proxyDirIndex, name, true);
- if (index < 0)
+ if (index == -1)
return E_INVALIDARG;
return BindToFolder_Internal(_proxy2->Files[_proxy2->Dirs[_proxyDirIndex].Items[index]].DirIndex, resultFolder);
}
int index = _proxy->FindSubDir(_proxyDirIndex, name);
- if (index < 0)
+ if (index == -1)
return E_INVALIDARG;
return BindToFolder_Internal(index, resultFolder);
COM_TRY_END
@@ -956,7 +960,7 @@ STDMETHODIMP CAgentFolder::BindToAltStreams(UInt32 index, IFolderFolder **result
{
unsigned arcIndex = _proxy2->Dirs[_proxyDirIndex].ArcIndex;
const CProxyFile2 &item = _proxy2->Files[arcIndex];
- if (item.AltDirIndex < 0)
+ if (item.AltDirIndex == -1)
return S_OK;
altDirIndex = item.AltDirIndex;
// parentFolder = _parentFolder;
@@ -972,7 +976,7 @@ STDMETHODIMP CAgentFolder::BindToAltStreams(UInt32 index, IFolderFolder **result
SET_realIndex_AND_dir_2
unsigned arcIndex = dir->Items[realIndex];
const CProxyFile2 &item = _proxy2->Files[arcIndex];
- if (item.AltDirIndex < 0)
+ if (item.AltDirIndex == -1)
return S_OK;
return BindToAltStreams_Internal(item.AltDirIndex, resultFolder);
}
@@ -1000,7 +1004,7 @@ STDMETHODIMP CAgentFolder::BindToAltStreams(const wchar_t *name, IFolderFolder *
FOR_VECTOR (i, dir.Items)
{
const CProxyFile2 &file = _proxy2->Files[dir.Items[i]];
- if (file.AltDirIndex >= 0)
+ if (file.AltDirIndex != -1)
if (CompareFileNames(file.Name, name) == 0)
return BindToAltStreams_Internal(file.AltDirIndex, resultFolder);
}
@@ -1036,7 +1040,7 @@ STDMETHODIMP CAgentFolder::AreAltStreamsSupported(UInt32 index, Int32 *isSupport
arcIndex = dir->Items[realIndex];
}
- if (_proxy2->Files[arcIndex].AltDirIndex >= 0)
+ if (_proxy2->Files[arcIndex].AltDirIndex != -1)
*isSupported = BoolToInt(true);
return S_OK;
}
@@ -1062,18 +1066,18 @@ STDMETHODIMP CAgentFolder::BindToParentFolder(IFolderFolder **resultFolder)
else
{
const CProxyDir2 &fold = _proxy2->Dirs[_proxyDirIndex];
- const CProxyFile2 &file = _proxy2->Files[fold.ArcIndex];
- int parentIndex = file.Parent;
- if (parentIndex < 0)
+ const CProxyFile2 &file = _proxy2->Files[(unsigned)fold.ArcIndex];
+ const int parentIndex = file.Parent;
+ if (parentIndex == -1)
proxyDirIndex = k_Proxy2_RootDirIndex;
else
- proxyDirIndex = _proxy2->Files[parentIndex].DirIndex;
+ proxyDirIndex = _proxy2->Files[(unsigned)parentIndex].DirIndex;
}
}
else
{
int parent = _proxy->Dirs[_proxyDirIndex].ParentDir;
- if (parent < 0)
+ if (parent == -1)
return S_OK;
proxyDirIndex = parent;
}
@@ -1239,8 +1243,8 @@ STDMETHODIMP CAgentFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value)
const CProxyDir2 &dir = _proxy2->Dirs[_proxyDirIndex];
if (propID == kpidName)
{
- if (dir.ArcIndex >= 0)
- prop = _proxy2->Files[dir.ArcIndex].Name;
+ if (dir.ArcIndex != -1)
+ prop = _proxy2->Files[(unsigned)dir.ArcIndex].Name;
}
else if (propID == kpidPath)
{
@@ -1477,8 +1481,8 @@ STDMETHODIMP CAgentFolder::Extract(const UInt32 *indices,
false, // multiArchives
pathMode,
overwriteMode,
- true // keepEmptyDirPrefixes
- );
+ _zoneMode,
+ k_keepEmptyDirPrefixes);
if (extractCallback2)
extractCallback2->SetTotal(_agentSpec->GetArc().GetEstmatedPhySize());
@@ -1500,6 +1504,15 @@ STDMETHODIMP CAgentFolder::Extract(const UInt32 *indices,
extractNtOptions.ReplaceColonForAltStream = IntToBool(replaceAltStreamColon);
+ extractCallbackSpec->InitBeforeNewArchive();
+
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ if (_zoneMode != NExtract::NZoneIdMode::kNone)
+ {
+ ReadZoneFile_Of_BaseFile(us2fs(_agentSpec->_archiveFilePath), extractCallbackSpec->ZoneBuf);
+ }
+ #endif
+
extractCallbackSpec->Init(
extractNtOptions,
NULL, &_agentSpec->GetArc(),
@@ -1645,8 +1658,8 @@ STDMETHODIMP CAgent::Open(
CArc &arc = _archiveLink.Arcs.Back();
if (!inStream)
{
- arc.MTimeDefined = !fi.IsDevice;
- arc.MTime = fi.MTime;
+ arc.MTime.Set_From_FiTime(fi.MTime);
+ arc.MTime.Def = !fi.IsDevice;
}
ArchiveType = GetTypeOfArc(arc);
@@ -1783,8 +1796,8 @@ STDMETHODIMP CAgent::Extract(
false, // multiArchives
pathMode,
overwriteMode,
- true // keepEmptyDirPrefixes
- );
+ NExtract::NZoneIdMode::kNone,
+ k_keepEmptyDirPrefixes);
CExtractNtOptions extractNtOptions;
extractNtOptions.AltStreams.Val = true; // change it!!!
diff --git a/CPP/7zip/UI/Agent/Agent.h b/CPP/7zip/UI/Agent/Agent.h
index e9fe4103..8e8a4c7d 100644..100755
--- a/CPP/7zip/UI/Agent/Agent.h
+++ b/CPP/7zip/UI/Agent/Agent.h
@@ -58,7 +58,7 @@ class CAgentFolder:
public IArchiveFolder,
public IArchiveFolderInternal,
public IInArchiveGetStream,
- // public IFolderSetReplaceAltStreamCharsMode,
+ public IFolderSetZoneIdMode,
#ifdef NEW_FOLDER_INTERFACE
public IFolderOperations,
public IFolderSetFlatMode,
@@ -78,7 +78,7 @@ public:
MY_QUERYINTERFACE_ENTRY(IArchiveFolder)
MY_QUERYINTERFACE_ENTRY(IArchiveFolderInternal)
MY_QUERYINTERFACE_ENTRY(IInArchiveGetStream)
- // MY_QUERYINTERFACE_ENTRY(IFolderSetReplaceAltStreamCharsMode)
+ MY_QUERYINTERFACE_ENTRY(IFolderSetZoneIdMode)
#ifdef NEW_FOLDER_INTERFACE
MY_QUERYINTERFACE_ENTRY(IFolderOperations)
MY_QUERYINTERFACE_ENTRY(IFolderSetFlatMode)
@@ -92,7 +92,7 @@ public:
void GetRealIndices(const UInt32 *indices, UInt32 numItems,
bool includeAltStreams, bool includeFolderSubItemsInFlatMode, CUIntVector &realIndices) const;
- // INTERFACE_FolderSetReplaceAltStreamCharsMode(;)
+ INTERFACE_IFolderSetZoneIdMode(;)
INTERFACE_FolderFolder(;)
INTERFACE_FolderAltStreams(;)
@@ -123,6 +123,7 @@ public:
_isAltStreamFolder(false),
_flatMode(false),
_loadAltStreams(false) // _loadAltStreams alt streams works in flat mode, but we don't use it now
+ , _zoneMode(NExtract::NZoneIdMode::kNone)
/* , _replaceAltStreamCharsMode(0) */
{}
@@ -169,6 +170,7 @@ public:
bool _flatMode;
bool _loadAltStreams; // in Flat mode
// Int32 _replaceAltStreamCharsMode;
+ NExtract::NZoneIdMode::EEnum _zoneMode;
};
class CAgent:
diff --git a/CPP/7zip/UI/Agent/AgentOut.cpp b/CPP/7zip/UI/Agent/AgentOut.cpp
index fae0e224..da8da6cd 100644..100755
--- a/CPP/7zip/UI/Agent/AgentOut.cpp
+++ b/CPP/7zip/UI/Agent/AgentOut.cpp
@@ -12,6 +12,8 @@
#include "../../Common/FileStreams.h"
+#include "../../Archive/Common/ItemNameUtils.h"
+
#include "Agent.h"
#include "UpdateCallbackAgent.h"
@@ -67,8 +69,8 @@ static HRESULT EnumerateArchiveItems(CAgent *agent,
unsigned arcIndex = item.SubFiles[i];
const CProxyFile &fileItem = agent->_proxy->Files[arcIndex];
CArcItem ai;
- RINOK(agent->GetArc().GetItemMTime(arcIndex, ai.MTime, ai.MTimeDefined));
- RINOK(agent->GetArc().GetItemSize(arcIndex, ai.Size, ai.SizeDefined));
+ RINOK(agent->GetArc().GetItem_MTime(arcIndex, ai.MTime));
+ RINOK(agent->GetArc().GetItem_Size(arcIndex, ai.Size, ai.Size_Defined));
ai.IsDir = false;
ai.Name = prefix + fileItem.Name;
ai.Censored = true; // test it
@@ -83,9 +85,9 @@ static HRESULT EnumerateArchiveItems(CAgent *agent,
if (dirItem.IsLeaf())
{
CArcItem ai;
- RINOK(agent->GetArc().GetItemMTime(dirItem.ArcIndex, ai.MTime, ai.MTimeDefined));
+ RINOK(agent->GetArc().GetItem_MTime(dirItem.ArcIndex, ai.MTime));
ai.IsDir = true;
- ai.SizeDefined = false;
+ ai.Size_Defined = false;
ai.Name = fullName;
ai.Censored = true; // test it
ai.IndexInServer = dirItem.ArcIndex;
@@ -111,18 +113,18 @@ static HRESULT EnumerateArchiveItems2(const CAgent *agent,
ai.IndexInServer = arcIndex;
ai.Name = prefix + file.Name;
ai.Censored = true; // test it
- RINOK(agent->GetArc().GetItemMTime(arcIndex, ai.MTime, ai.MTimeDefined));
+ RINOK(agent->GetArc().GetItem_MTime(arcIndex, ai.MTime));
ai.IsDir = file.IsDir();
- ai.SizeDefined = false;
+ ai.Size_Defined = false;
ai.IsAltStream = file.IsAltStream;
if (!ai.IsDir)
{
- RINOK(agent->GetArc().GetItemSize(arcIndex, ai.Size, ai.SizeDefined));
+ RINOK(agent->GetArc().GetItem_Size(arcIndex, ai.Size, ai.Size_Defined));
ai.IsDir = false;
}
arcItems.Add(ai);
- if (file.AltDirIndex >= 0)
+ if (file.AltDirIndex != -1)
{
RINOK(EnumerateArchiveItems2(agent, file.AltDirIndex, ai.Name + L':', arcItems));
}
@@ -264,10 +266,13 @@ STDMETHODIMP CAgent::DoOperation(
#endif
}
- NFileTimeType::EEnum fileTimeType;
+ NFileTimeType::EEnum fileTimeType = NFileTimeType::kNotDefined;
UInt32 value;
RINOK(outArchive->GetFileTimeType(&value));
-
+ // we support any future fileType here.
+ // 22.00:
+ fileTimeType = (NFileTimeType::EEnum)value;
+ /*
switch (value)
{
case NFileTimeType::kWindows:
@@ -276,8 +281,11 @@ STDMETHODIMP CAgent::DoOperation(
fileTimeType = NFileTimeType::EEnum(value);
break;
default:
+ {
return E_FAIL;
+ }
}
+ */
CObjectVector<CArcItem> arcItems;
@@ -389,11 +397,11 @@ STDMETHODIMP CAgent::DoOperation(
FOR_VECTOR(i, updatePairs2)
{
const CUpdatePair2 &up = updatePairs2[i];
- if (up.DirIndex >= 0 && up.NewData)
+ if (up.DirIndex != -1 && up.NewData)
{
- const CDirItem &di = dirItems.Items[up.DirIndex];
+ const CDirItem &di = dirItems.Items[(unsigned)up.DirIndex];
if (!di.IsDir() && di.Size == 0)
- processedItems[up.DirIndex] = 1;
+ processedItems[(unsigned)up.DirIndex] = 1;
}
}
}
@@ -452,7 +460,7 @@ STDMETHODIMP CAgent::DeleteItems(ISequentialOutStream *outArchiveStream,
if (curIndex < realIndices.Size())
if (realIndices[curIndex] == i)
{
- RINOK(GetArc().GetItemPath2(i, deletePath));
+ RINOK(GetArc().GetItem_Path2(i, deletePath));
RINOK(updateCallback100->DeleteOperation(deletePath));
curIndex++;
@@ -548,11 +556,14 @@ HRESULT CAgent::RenameItem(ISequentialOutStream *outArchiveStream,
true, // includeFolderSubItemsInFlatMode
realIndices);
- int mainRealIndex = _agentFolder->GetRealIndex(indices[0]);
-
- UString fullPrefix = _agentFolder->GetFullPrefix(indices[0]);
- UString oldItemPath = fullPrefix + _agentFolder->GetName(indices[0]);
- UString newItemPath = fullPrefix + newItemName;
+ const UInt32 ind0 = indices[0];
+ const int mainRealIndex = _agentFolder->GetRealIndex(ind0);
+ const UString fullPrefix = _agentFolder->GetFullPrefix(ind0);
+ UString name = _agentFolder->GetName(ind0);
+ // 22.00 : we normalize name
+ NArchive::NItemName::NormalizeSlashes_in_FileName_for_OsPath(name);
+ const UString oldItemPath = fullPrefix + name;
+ const UString newItemPath = fullPrefix + newItemName;
UStringVector newNames;
@@ -568,10 +579,10 @@ HRESULT CAgent::RenameItem(ISequentialOutStream *outArchiveStream,
if (realIndices[curIndex] == i)
{
up2.NewProps = true;
- RINOK(GetArc().IsItemAnti(i, up2.IsAnti)); // it must work without that line too.
+ RINOK(GetArc().IsItem_Anti(i, up2.IsAnti)); // it must work without that line too.
UString oldFullPath;
- RINOK(GetArc().GetItemPath2(i, oldFullPath));
+ RINOK(GetArc().GetItem_Path2(i, oldFullPath));
if (!IsPath1PrefixedByPath2(oldFullPath, oldItemPath))
return E_INVALIDARG;
diff --git a/CPP/7zip/UI/Agent/AgentProxy.cpp b/CPP/7zip/UI/Agent/AgentProxy.cpp
index f0acd20b..4c9c386b 100644..100755
--- a/CPP/7zip/UI/Agent/AgentProxy.cpp
+++ b/CPP/7zip/UI/Agent/AgentProxy.cpp
@@ -18,6 +18,8 @@
#include "../../../Windows/PropVariant.h"
#include "../../../Windows/PropVariantConv.h"
+#include "../../Archive/Common/ItemNameUtils.h"
+
#include "AgentProxy.h"
using namespace NWindows;
@@ -33,12 +35,12 @@ int CProxyArc::FindSubDir(unsigned dirIndex, const wchar_t *name, unsigned &inse
insertPos = left;
return -1;
}
- unsigned mid = (left + right) / 2;
- unsigned dirIndex2 = subDirs[mid];
- int compare = CompareFileNames(name, Dirs[dirIndex2].Name);
- if (compare == 0)
+ const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2);
+ const unsigned dirIndex2 = subDirs[mid];
+ const int comp = CompareFileNames(name, Dirs[dirIndex2].Name);
+ if (comp == 0)
return dirIndex2;
- if (compare < 0)
+ if (comp < 0)
right = mid;
else
left = mid + 1;
@@ -67,12 +69,12 @@ unsigned CProxyArc::AddDir(unsigned dirIndex, int arcIndex, const UString &name)
{
unsigned insertPos;
int subDirIndex = FindSubDir(dirIndex, name, insertPos);
- if (subDirIndex >= 0)
+ if (subDirIndex != -1)
{
- if (arcIndex >= 0)
+ if (arcIndex != -1)
{
- CProxyDir &item = Dirs[subDirIndex];
- if (item.ArcIndex < 0)
+ CProxyDir &item = Dirs[(unsigned)subDirIndex];
+ if (item.ArcIndex == -1)
item.ArcIndex = arcIndex;
}
return subDirIndex;
@@ -98,27 +100,31 @@ void CProxyDir::Clear()
void CProxyArc::GetDirPathParts(int dirIndex, UStringVector &pathParts) const
{
pathParts.Clear();
- while (dirIndex >= 0)
+ while (dirIndex != -1)
{
const CProxyDir &dir = Dirs[dirIndex];
dirIndex = dir.ParentDir;
- if (dirIndex < 0)
+ if (dirIndex == -1)
break;
pathParts.Insert(0, dir.Name);
+ // 22.00: we normalize name
+ NArchive::NItemName::NormalizeSlashes_in_FileName_for_OsPath(pathParts[0]);
}
}
UString CProxyArc::GetDirPath_as_Prefix(int dirIndex) const
{
UString s;
- while (dirIndex >= 0)
+ while (dirIndex != -1)
{
const CProxyDir &dir = Dirs[dirIndex];
dirIndex = dir.ParentDir;
- if (dirIndex < 0)
+ if (dirIndex == -1)
break;
s.InsertAtFront(WCHAR_PATH_SEPARATOR);
s.Insert(0, dir.Name);
+ // 22.00: we normalize name
+ NArchive::NItemName::NormalizeSlashes_in_FileName_for_OsPath(s.GetBuf(), MyStringLen(dir.Name));
}
return s;
}
@@ -251,7 +257,7 @@ HRESULT CProxyArc::Load(const CArc &arc, IProgress *progress)
{
if (progress && (i & 0xFFFF) == 0)
{
- UInt64 currentItemIndex = i;
+ const UInt64 currentItemIndex = i;
RINOK(progress->SetCompleted(&currentItemIndex));
}
@@ -259,9 +265,9 @@ HRESULT CProxyArc::Load(const CArc &arc, IProgress *progress)
unsigned len = 0;
bool isPtrName = false;
- #if WCHAR_PATH_SEPARATOR != L'/'
- wchar_t replaceFromChar = 0;
- #endif
+ #if WCHAR_PATH_SEPARATOR != L'/'
+ wchar_t separatorChar = WCHAR_PATH_SEPARATOR;
+ #endif
#if defined(MY_CPU_LE) && defined(_WIN32)
// it works only if (sizeof(wchar_t) == 2)
@@ -278,9 +284,9 @@ HRESULT CProxyArc::Load(const CArc &arc, IProgress *progress)
len = size / 2 - 1;
s = (const wchar_t *)p;
isPtrName = true;
- #if WCHAR_PATH_SEPARATOR != L'/'
- replaceFromChar = L'\\';
- #endif
+ #if WCHAR_PATH_SEPARATOR != L'/'
+ separatorChar = L'/'; // 0
+ #endif
}
}
if (!s)
@@ -297,7 +303,7 @@ HRESULT CProxyArc::Load(const CArc &arc, IProgress *progress)
return E_FAIL;
if (len == 0)
{
- RINOK(arc.GetDefaultItemPath(i, path));
+ RINOK(arc.GetItem_DefaultPath(i, path));
len = path.Len();
s = path;
}
@@ -328,16 +334,12 @@ HRESULT CProxyArc::Load(const CArc &arc, IProgress *progress)
for (unsigned j = 0; j < len; j++)
{
const wchar_t c = s[j];
- if (c == WCHAR_PATH_SEPARATOR || c == L'/')
- {
+ if (c == L'/'
#if WCHAR_PATH_SEPARATOR != L'/'
- if (c == replaceFromChar)
- {
- // s.ReplaceOneCharAtPos(j, WCHAR_IN_FILE_NAME_BACKSLASH_REPLACEMENT);
- continue;
- }
+ || (c == separatorChar)
#endif
-
+ )
+ {
const unsigned kLevelLimit = 1 << 10;
if (numLevels <= kLevelLimit)
{
@@ -345,6 +347,8 @@ HRESULT CProxyArc::Load(const CArc &arc, IProgress *progress)
name = "[LONG_PATH]";
else
name.SetFrom(s + namePos, j - namePos);
+ // 22.00: we can normalize dir here
+ // NArchive::NItemName::NormalizeSlashes_in_FileName_for_OsPath(name);
curItem = AddDir(curItem, -1, name);
}
namePos = j + 1;
@@ -384,6 +388,8 @@ HRESULT CProxyArc::Load(const CArc &arc, IProgress *progress)
if (isDir)
{
name = s;
+ // 22.00: we can normalize dir here
+ // NArchive::NItemName::NormalizeSlashes_in_FileName_for_OsPath(name);
AddDir(curItem, (int)i, name);
}
else
@@ -418,14 +424,14 @@ void CProxyArc2::GetDirPathParts(int dirIndex, UStringVector &pathParts, bool &i
while (dirIndex >= (int)k_Proxy2_NumRootDirs)
{
const CProxyDir2 &dir = Dirs[dirIndex];
- const CProxyFile2 &file = Files[dir.ArcIndex];
+ const CProxyFile2 &file = Files[(unsigned)dir.ArcIndex];
if (pathParts.IsEmpty() && dirIndex == file.AltDirIndex)
isAltStreamDir = true;
pathParts.Insert(0, file.Name);
int par = file.Parent;
- if (par < 0)
+ if (par == -1)
break;
- dirIndex = Files[par].DirIndex;
+ dirIndex = Files[(unsigned)par].DirIndex;
}
}
@@ -436,7 +442,7 @@ bool CProxyArc2::IsAltDir(unsigned dirIndex) const
if (dirIndex == k_Proxy2_AltRootDirIndex)
return true;
const CProxyDir2 &dir = Dirs[dirIndex];
- const CProxyFile2 &file = Files[dir.ArcIndex];
+ const CProxyFile2 &file = Files[(unsigned)dir.ArcIndex];
return ((int)dirIndex == file.AltDirIndex);
}
@@ -448,7 +454,7 @@ UString CProxyArc2::GetDirPath_as_Prefix(unsigned dirIndex, bool &isAltStreamDir
isAltStreamDir = true;
else if (dirIndex >= k_Proxy2_NumRootDirs)
{
- const CProxyFile2 &file = Files[dir.ArcIndex];
+ const CProxyFile2 &file = Files[(unsigned)dir.ArcIndex];
isAltStreamDir = ((int)dirIndex == file.AltDirIndex);
}
return dir.PathPrefix;
@@ -458,9 +464,9 @@ void CProxyArc2::AddRealIndices_of_ArcItem(unsigned arcIndex, bool includeAltStr
{
realIndices.Add(arcIndex);
const CProxyFile2 &file = Files[arcIndex];
- if (file.DirIndex >= 0)
+ if (file.DirIndex != -1)
AddRealIndices_of_Dir(file.DirIndex, includeAltStreams, realIndices);
- if (includeAltStreams && file.AltDirIndex >= 0)
+ if (includeAltStreams && file.AltDirIndex != -1)
AddRealIndices_of_Dir(file.AltDirIndex, includeAltStreams, realIndices);
}
@@ -520,15 +526,18 @@ void CProxyArc2::CalculateSizes(unsigned dirIndex, IInArchive *archive)
}
const CProxyFile2 &subFile = Files[index];
- if (subFile.DirIndex < 0)
+ if (subFile.DirIndex == -1)
{
dir.NumSubFiles++;
}
else
{
+ // 22.00: we normalize name
+ UString s = subFile.Name;
+ NArchive::NItemName::NormalizeSlashes_in_FileName_for_OsPath(s);
dir.NumSubDirs++;
CProxyDir2 &f = Dirs[subFile.DirIndex];
- f.PathPrefix = dir.PathPrefix + subFile.Name + WCHAR_PATH_SEPARATOR;
+ f.PathPrefix = dir.PathPrefix + s + WCHAR_PATH_SEPARATOR;
CalculateSizes(subFile.DirIndex, archive);
dir.Size += f.Size;
dir.PackSize += f.PackSize;
@@ -539,7 +548,7 @@ void CProxyArc2::CalculateSizes(unsigned dirIndex, IInArchive *archive)
dir.CrcIsDefined = false;
}
- if (subFile.AltDirIndex < 0)
+ if (subFile.AltDirIndex == -1)
{
// dir.NumSubFiles++;
}
@@ -688,12 +697,12 @@ HRESULT CProxyArc2::Load(const CArc &arc, IProgress *progress)
if (file.IsAltStream)
{
- if (file.Parent < 0)
+ if (file.Parent == -1)
dirIndex = k_Proxy2_AltRootDirIndex;
else
{
- int &folderIndex2 = Files[file.Parent].AltDirIndex;
- if (folderIndex2 < 0)
+ int &folderIndex2 = Files[(unsigned)file.Parent].AltDirIndex;
+ if (folderIndex2 == -1)
{
folderIndex2 = Dirs.Size();
CProxyDir2 &dir = Dirs.AddNew();
@@ -704,12 +713,12 @@ HRESULT CProxyArc2::Load(const CArc &arc, IProgress *progress)
}
else
{
- if (file.Parent < 0)
+ if (file.Parent == -1)
dirIndex = k_Proxy2_RootDirIndex;
else
{
- dirIndex = Files[file.Parent].DirIndex;
- if (dirIndex < 0)
+ dirIndex = Files[(unsigned)file.Parent].DirIndex;
+ if (dirIndex == -1)
return E_FAIL;
}
}
@@ -731,7 +740,7 @@ int CProxyArc2::FindItem(unsigned dirIndex, const wchar_t *name, bool foldersOnl
FOR_VECTOR (i, dir.Items)
{
const CProxyFile2 &file = Files[dir.Items[i]];
- if (foldersOnly && file.DirIndex < 0)
+ if (foldersOnly && file.DirIndex == -1)
continue;
if (CompareFileNames(file.Name, name) == 0)
return i;
diff --git a/CPP/7zip/UI/Agent/AgentProxy.h b/CPP/7zip/UI/Agent/AgentProxy.h
index f2cb3d7a..233174b4 100644..100755
--- a/CPP/7zip/UI/Agent/AgentProxy.h
+++ b/CPP/7zip/UI/Agent/AgentProxy.h
@@ -38,7 +38,7 @@ struct CProxyDir
~CProxyDir() { delete [](wchar_t *)(void *)Name; }
void Clear();
- bool IsLeaf() const { return ArcIndex >= 0; }
+ bool IsLeaf() const { return ArcIndex != -1; }
};
class CProxyArc
@@ -82,7 +82,7 @@ struct CProxyFile2
int GetDirIndex(bool forAltStreams) const { return forAltStreams ? AltDirIndex : DirIndex; }
- bool IsDir() const { return DirIndex >= 0; }
+ bool IsDir() const { return DirIndex != -1; }
CProxyFile2():
DirIndex(-1), AltDirIndex(-1), Parent(-1),
Name(NULL), NameLen(0),
@@ -145,7 +145,7 @@ public:
{
const CProxyFile2 &file = Files[arcIndex];
- if (file.Parent < 0)
+ if (file.Parent == -1)
return file.IsAltStream ?
k_Proxy2_AltRootDirIndex :
k_Proxy2_RootDirIndex;
diff --git a/CPP/7zip/UI/Agent/ArchiveFolder.cpp b/CPP/7zip/UI/Agent/ArchiveFolder.cpp
index a20b4f24..eca02ba1 100644..100755
--- a/CPP/7zip/UI/Agent/ArchiveFolder.cpp
+++ b/CPP/7zip/UI/Agent/ArchiveFolder.cpp
@@ -16,6 +16,12 @@ STDMETHODIMP CAgentFolder::SetReplaceAltStreamCharsMode(Int32 replaceAltStreamCh
}
*/
+STDMETHODIMP CAgentFolder::SetZoneIdMode(NExtract::NZoneIdMode::EEnum zoneMode)
+{
+ _zoneMode = zoneMode;
+ return S_OK;
+}
+
STDMETHODIMP CAgentFolder::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 numItems,
Int32 includeAltStreams, Int32 replaceAltStreamCharsMode,
const wchar_t *path, IFolderOperationsExtractCallback *callback)
diff --git a/CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp b/CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp
index 55457f45..55457f45 100644..100755
--- a/CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp
+++ b/CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp
diff --git a/CPP/7zip/UI/Agent/ArchiveFolderOut.cpp b/CPP/7zip/UI/Agent/ArchiveFolderOut.cpp
index 4a10ebec..cd18c996 100644..100755
--- a/CPP/7zip/UI/Agent/ArchiveFolderOut.cpp
+++ b/CPP/7zip/UI/Agent/ArchiveFolderOut.cpp
@@ -210,7 +210,7 @@ HRESULT CAgentFolder::CommonUpdateOperation(
FOR_VECTOR (i, pathParts)
{
int next = _proxy->FindSubDir(_proxyDirIndex, pathParts[i]);
- if (next < 0)
+ if (next == -1)
break;
_proxyDirIndex = next;
}
@@ -226,7 +226,7 @@ HRESULT CAgentFolder::CommonUpdateOperation(
{
bool dirOnly = (i + 1 < pathParts.Size() || !isAltStreamFolder);
int index = _proxy2->FindItem(_proxyDirIndex, pathParts[i], dirOnly);
- if (index < 0)
+ if (index == -1)
break;
const CProxyFile2 &file = _proxy2->Files[_proxy2->Dirs[_proxyDirIndex].Items[index]];
@@ -235,7 +235,7 @@ HRESULT CAgentFolder::CommonUpdateOperation(
_proxyDirIndex = file.DirIndex;
else
{
- if (file.AltDirIndex >= 0)
+ if (file.AltDirIndex != -1)
_proxyDirIndex = file.AltDirIndex;
break;
}
@@ -351,7 +351,7 @@ STDMETHODIMP CAgentFolder::CreateFolder(const wchar_t *name, IProgress *progress
}
else
{
- if (_proxy->FindSubDir(_proxyDirIndex, name) >= 0)
+ if (_proxy->FindSubDir(_proxyDirIndex, name) != -1)
return ERROR_ALREADY_EXISTS;
}
diff --git a/CPP/7zip/UI/Agent/IFolderArchive.h b/CPP/7zip/UI/Agent/IFolderArchive.h
index 565e37b0..92eb6160 100644..100755
--- a/CPP/7zip/UI/Agent/IFolderArchive.h
+++ b/CPP/7zip/UI/Agent/IFolderArchive.h
@@ -116,4 +116,13 @@ FOLDER_ARCHIVE_INTERFACE(IFolderScanProgress, 0x11)
INTERFACE_IFolderScanProgress(PURE)
};
+
+#define INTERFACE_IFolderSetZoneIdMode(x) \
+ STDMETHOD(SetZoneIdMode)(NExtract::NZoneIdMode::EEnum zoneMode) x; \
+
+FOLDER_ARCHIVE_INTERFACE(IFolderSetZoneIdMode, 0x12)
+{
+ INTERFACE_IFolderSetZoneIdMode(PURE)
+};
+
#endif
diff --git a/CPP/7zip/UI/Agent/StdAfx.h b/CPP/7zip/UI/Agent/StdAfx.h
index 2854ff3e..2854ff3e 100644..100755
--- a/CPP/7zip/UI/Agent/StdAfx.h
+++ b/CPP/7zip/UI/Agent/StdAfx.h
diff --git a/CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp b/CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp
index 53a13bb9..53a13bb9 100644..100755
--- a/CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp
+++ b/CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp
diff --git a/CPP/7zip/UI/Agent/UpdateCallbackAgent.h b/CPP/7zip/UI/Agent/UpdateCallbackAgent.h
index 4da7693c..4da7693c 100644..100755
--- a/CPP/7zip/UI/Agent/UpdateCallbackAgent.h
+++ b/CPP/7zip/UI/Agent/UpdateCallbackAgent.h
diff --git a/CPP/7zip/UI/Client7z/Client7z.cpp b/CPP/7zip/UI/Client7z/Client7z.cpp
index 0fa4cdad..a55fa22d 100644..100755
--- a/CPP/7zip/UI/Client7z/Client7z.cpp
+++ b/CPP/7zip/UI/Client7z/Client7z.cpp
@@ -33,17 +33,29 @@ HINSTANCE g_hInstance;
HINSTANCE g_hInstance = 0;
#endif
-// You 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) 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;
@@ -229,6 +241,86 @@ static const char * const kIsNotArc = "Is not archive";
static const char * const kHeadersError = "Headers Error";
+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 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;
+ }
+};
+
+
+
class CArchiveExtractCallback:
public IArchiveExtractCallback,
public ICryptoGetTextPassword,
@@ -257,11 +349,10 @@ private:
bool _extractMode;
struct CProcessedFileInfo
{
- FILETIME MTime;
+ CArcTime MTime;
UInt32 Attrib;
bool isDir;
- bool AttribDefined;
- bool MTimeDefined;
+ bool Attrib_Defined;
} _processedFileInfo;
COutFileStream *_outFileStreamSpec;
@@ -328,32 +419,31 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index,
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));
{
+ _processedFileInfo.MTime.Clear();
// Get Modified Time
NCOM::CPropVariant prop;
RINOK(_archiveHandler->GetProperty(index, kpidMTime, &prop));
- _processedFileInfo.MTimeDefined = false;
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;
@@ -483,12 +573,16 @@ STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult)
if (_outFileStream)
{
- if (_processedFileInfo.MTimeDefined)
- _outFileStreamSpec->SetMTime(&_processedFileInfo.MTime);
+ if (_processedFileInfo.MTime.Def)
+ {
+ CFiTime ft;
+ _processedFileInfo.MTime.Write_To_FiTime(ft);
+ _outFileStreamSpec->SetMTime(&ft);
+ }
RINOK(_outFileStreamSpec->Close());
}
_outFileStream.Release();
- if (_extractMode && _processedFileInfo.AttribDefined)
+ if (_extractMode && _processedFileInfo.Attrib_Defined)
SetFileAttrib_PosixHighDetect(_diskFilePath, _processedFileInfo.Attrib);
PrintNewLine();
return S_OK;
@@ -513,17 +607,14 @@ 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;
-
- bool isDir() const { return (Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0 ; }
+ UString Path_For_Handler;
+ FString FullPath; // for filesystem
+
+ CDirItem(const NWindows::NFile::NFind::CFileInfo &fi):
+ CFileInfoBase(fi)
+ {}
};
class CArchiveUpdateCallback:
@@ -618,16 +709,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);
@@ -657,9 +749,9 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream
RINOK(Finilize());
const CDirItem &dirItem = (*DirItems)[index];
- GetStream2(dirItem.Name);
+ GetStream2(dirItem.Path_For_Handler);
- if (dirItem.isDir())
+ if (dirItem.IsDir())
return S_OK;
{
@@ -848,7 +940,6 @@ int MY_CDECL main(int numArgs, const char *args[])
unsigned i;
for (i = 1; i < params.Size(); i++)
{
- CDirItem di;
const FString &name = params[i];
NFind::CFileInfo fi;
@@ -857,13 +948,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);
}
@@ -894,12 +982,14 @@ int MY_CDECL main(int numArgs, const char *args[])
{
const wchar_t *names[] =
{
+ L"m",
L"s",
L"x"
};
const unsigned kNumProps = ARRAY_SIZE(names);
NCOM::CPropVariant values[kNumProps] =
{
+ L"lzma",
false, // solid mode OFF
(UInt32)9 // compression level = 9 - ultra
};
@@ -910,7 +1000,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;
+ }
}
*/
@@ -1035,7 +1129,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/CPP/7zip/UI/Client7z/Client7z.dsp b/CPP/7zip/UI/Client7z/Client7z.dsp
index b412c8e9..b412c8e9 100644..100755
--- a/CPP/7zip/UI/Client7z/Client7z.dsp
+++ b/CPP/7zip/UI/Client7z/Client7z.dsp
diff --git a/CPP/7zip/UI/Client7z/Client7z.dsw b/CPP/7zip/UI/Client7z/Client7z.dsw
index 598a6d3f..598a6d3f 100644..100755
--- a/CPP/7zip/UI/Client7z/Client7z.dsw
+++ b/CPP/7zip/UI/Client7z/Client7z.dsw
diff --git a/CPP/7zip/UI/Client7z/StdAfx.cpp b/CPP/7zip/UI/Client7z/StdAfx.cpp
index d0feea85..d0feea85 100644..100755
--- a/CPP/7zip/UI/Client7z/StdAfx.cpp
+++ b/CPP/7zip/UI/Client7z/StdAfx.cpp
diff --git a/CPP/7zip/UI/Client7z/StdAfx.h b/CPP/7zip/UI/Client7z/StdAfx.h
index 2854ff3e..2854ff3e 100644..100755
--- a/CPP/7zip/UI/Client7z/StdAfx.h
+++ b/CPP/7zip/UI/Client7z/StdAfx.h
diff --git a/CPP/7zip/UI/Client7z/makefile b/CPP/7zip/UI/Client7z/makefile
index 988701ef..988701ef 100644..100755
--- a/CPP/7zip/UI/Client7z/makefile
+++ b/CPP/7zip/UI/Client7z/makefile
diff --git a/CPP/7zip/UI/Client7z/makefile.gcc b/CPP/7zip/UI/Client7z/makefile.gcc
index b65095bf..b65095bf 100644..100755
--- a/CPP/7zip/UI/Client7z/makefile.gcc
+++ b/CPP/7zip/UI/Client7z/makefile.gcc
diff --git a/CPP/7zip/UI/Client7z/resource.rc b/CPP/7zip/UI/Client7z/resource.rc
index 462df6fa..462df6fa 100644..100755
--- a/CPP/7zip/UI/Client7z/resource.rc
+++ b/CPP/7zip/UI/Client7z/resource.rc
diff --git a/CPP/7zip/UI/Common/ArchiveCommandLine.cpp b/CPP/7zip/UI/Common/ArchiveCommandLine.cpp
index 91ef0382..d88c8516 100644..100755
--- a/CPP/7zip/UI/Common/ArchiveCommandLine.cpp
+++ b/CPP/7zip/UI/Common/ArchiveCommandLine.cpp
@@ -160,7 +160,11 @@ enum Enum
kSymLinks_AllowDangerous,
kSymLinks,
kNtSecurity,
+
+ kStoreOwnerId,
+ kStoreOwnerName,
+ kZoneFile,
kAltStreams,
kReplaceColonForAltStream,
kWriteToAltStreamIfColon,
@@ -304,7 +308,11 @@ static const CSwitchForm kSwitchForms[] =
{ "snld", SWFRM_MINUS },
{ "snl", SWFRM_MINUS },
{ "sni", SWFRM_SIMPLE },
+
+ { "snoi", SWFRM_MINUS },
+ { "snon", SWFRM_MINUS },
+ { "snz", SWFRM_STRING_SINGL(0) },
{ "sns", SWFRM_MINUS },
{ "snr", SWFRM_SIMPLE },
{ "snc", SWFRM_SIMPLE },
@@ -1032,9 +1040,9 @@ 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;
}
@@ -1367,6 +1375,9 @@ 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);
@@ -1420,12 +1431,28 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
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();
@@ -1549,6 +1576,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)
diff --git a/CPP/7zip/UI/Common/ArchiveCommandLine.h b/CPP/7zip/UI/Common/ArchiveCommandLine.h
index ff4f28ca..745f999d 100644..100755
--- a/CPP/7zip/UI/Common/ArchiveCommandLine.h
+++ b/CPP/7zip/UI/Common/ArchiveCommandLine.h
@@ -51,7 +51,7 @@ struct CArcCmdLineOptions
bool HelpMode;
// bool LargePages;
- bool CaseSensitiveChange;
+ bool CaseSensitive_Change;
bool CaseSensitive;
bool IsInTerminal;
@@ -97,6 +97,9 @@ struct CArcCmdLineOptions
CBoolPair AltStreams;
CBoolPair HardLinks;
CBoolPair SymLinks;
+
+ CBoolPair StoreOwnerId;
+ CBoolPair StoreOwnerName;
CUpdateOptions UpdateOptions;
CHashOptions HashOptions;
@@ -117,7 +120,7 @@ struct CArcCmdLineOptions
CArcCmdLineOptions():
HelpMode(false),
// LargePages(false),
- CaseSensitiveChange(false),
+ CaseSensitive_Change(false),
CaseSensitive(false),
IsInTerminal(false),
diff --git a/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp b/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp
index 73c191e4..a574f136 100644..100755
--- a/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp
+++ b/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp
@@ -95,6 +95,83 @@ bool InitLocalPrivileges()
#endif // _USE_SECURITY_CODE
+
+#if defined(_WIN32) && !defined(UNDER_CE) && !defined(_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 = 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
@@ -190,9 +267,9 @@ HRESULT CArchiveExtractCallback::PrepareHardLinks(const CRecordVector<UInt32> *r
CArchiveExtractCallback::CArchiveExtractCallback():
_arc(NULL),
- WriteCTime(true),
- WriteATime(true),
- WriteMTime(true),
+ Write_CTime(true),
+ Write_ATime(true),
+ Write_MTime(true),
_multiArchives(false)
{
LocalProgressSpec = new CLocalProgress();
@@ -204,6 +281,13 @@ CArchiveExtractCallback::CArchiveExtractCallback():
}
+void CArchiveExtractCallback::InitBeforeNewArchive()
+{
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ ZoneBuf.Free();
+ #endif
+}
+
void CArchiveExtractCallback::Init(
const CExtractNtOptions &ntOptions,
const NWildcard::CCensorNode *wildcardCensor,
@@ -240,13 +324,19 @@ void CArchiveExtractCallback::Init(
_progressTotal_Defined = true;
_extractCallback2 = extractCallback2;
+
_compressProgress.Release();
_extractCallback2.QueryInterface(IID_ICompressProgressInfo, &_compressProgress);
+
+ _callbackMessage.Release();
_extractCallback2.QueryInterface(IID_IArchiveExtractCallbackMessage, &_callbackMessage);
+
+ _folderArchiveExtractCallback2.Release();
_extractCallback2.QueryInterface(IID_IFolderArchiveExtractCallback2, &_folderArchiveExtractCallback2);
#ifndef _SFX
+ ExtractToStreamCallback.Release();
_extractCallback2.QueryInterface(IID_IFolderExtractToStreamCallback, &ExtractToStreamCallback);
if (ExtractToStreamCallback)
{
@@ -416,26 +506,22 @@ void CArchiveExtractCallback::CreateComplexDirectory(const UStringVector &dirPat
}
-HRESULT CArchiveExtractCallback::GetTime(UInt32 index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined)
+HRESULT CArchiveExtractCallback::GetTime(UInt32 index, PROPID propID, CArcTime &ft)
{
- filetimeIsDefined = false;
- filetime.dwLowDateTime = 0;
- filetime.dwHighDateTime = 0;
+ ft.Clear();
NCOM::CPropVariant 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, _curSizeDefined);
}
static void AddPathToMessage(UString &s, const FString &path)
@@ -454,8 +540,9 @@ HRESULT CArchiveExtractCallback::SendMessageError(const char *message, const FSt
HRESULT CArchiveExtractCallback::SendMessageError_with_LastError(const char *message, const FString &path)
{
DWORD errorCode = GetLastError();
+ if (errorCode == 0)
+ errorCode = (DWORD)E_FAIL;
UString s (message);
- if (errorCode != 0)
{
s += " : ";
s += NError::MyFormatMessage(errorCode);
@@ -843,13 +930,58 @@ HRESULT CArchiveExtractCallback::ReadLink()
#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.AttribDefined = false;
+ _fi.Attrib_Defined = false;
+
+ #ifndef _WIN32
+ _fi.Owner.Clear();
+ _fi.Group.Clear();
+ #endif
{
NCOM::CPropVariant prop;
@@ -868,15 +1000,25 @@ HRESULT CArchiveExtractCallback::Read_fi_Props()
if (prop.vt == VT_UI4)
{
_fi.Attrib = prop.ulVal;
- _fi.AttribDefined = true;
+ _fi.Attrib_Defined = true;
}
else if (prop.vt != VT_EMPTY)
return E_FAIL;
}
- RINOK(GetTime(index, kpidCTime, _fi.CTime, _fi.CTimeDefined));
- RINOK(GetTime(index, kpidATime, _fi.ATime, _fi.ATimeDefined));
- RINOK(GetTime(index, kpidMTime, _fi.MTime, _fi.MTimeDefined));
+ 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;
}
@@ -923,6 +1065,39 @@ void CArchiveExtractCallback::CorrectPathParts()
}
+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()
{
@@ -948,30 +1123,9 @@ void CArchiveExtractCallback::CreateFolders()
return;
CDirPathTime pt;
-
- pt.CTime = _fi.CTime;
- pt.CTimeDefined = (WriteCTime && _fi.CTimeDefined);
-
- pt.ATime = _fi.ATime;
- pt.ATimeDefined = (WriteATime && _fi.ATimeDefined);
-
- pt.MTimeDefined = false;
-
- if (WriteMTime)
- {
- if (_fi.MTimeDefined)
- {
- pt.MTime = _fi.MTime;
- pt.MTimeDefined = true;
- }
- else if (_arc->MTimeDefined)
- {
- pt.MTime = _arc->MTime;
- pt.MTimeDefined = true;
- }
- }
-
- if (pt.MTimeDefined || pt.ATimeDefined || pt.CTimeDefined)
+ GetFiTimesCAM(pt);
+
+ if (pt.IsSomeTimeDefined())
{
pt.Path = fullPathNew;
pt.SetDirTime();
@@ -1006,10 +1160,13 @@ HRESULT CArchiveExtractCallback::CheckExistFile(FString &fullProcessedPath, bool
/* (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), &fileInfo.MTime, &fileInfo.Size, _item.Path,
- _fi.MTimeDefined ? &_fi.MTime : NULL,
+ fs2us(realFullProcessedPath), &ft1, &fileInfo.Size, _item.Path,
+ _fi.MTime.Def ? &_fi.MTime.FT : NULL,
_curSizeDefined ? &_curSize : NULL,
&overwriteResult))
@@ -1126,7 +1283,7 @@ HRESULT CArchiveExtractCallback::GetExtractStream(CMyComPtr<ISequentialOutStream
const UInt32 index = _index;
bool isAnti = false;
- RINOK(_arc->IsItemAnti(index, isAnti));
+ RINOK(_arc->IsItem_Anti(index, isAnti));
CorrectPathParts();
UString processedPath (MakePathFromParts(_item.PathParts));
@@ -1147,8 +1304,8 @@ HRESULT CArchiveExtractCallback::GetExtractStream(CMyComPtr<ISequentialOutStream
#ifdef SUPPORT_ALT_STREAMS
if (_item.IsAltStream && _item.ParentIndex != (UInt32)(Int32)-1)
{
- int renIndex = _renamedFiles.FindInSorted(CIndexToPathPair(_item.ParentIndex));
- if (renIndex >= 0)
+ const int renIndex = _renamedFiles.FindInSorted(CIndexToPathPair(_item.ParentIndex));
+ if (renIndex != -1)
{
const CIndexToPathPair &pair = _renamedFiles[(unsigned)renIndex];
fullProcessedPath = pair.Path;
@@ -1224,8 +1381,8 @@ HRESULT CArchiveExtractCallback::GetExtractStream(CMyComPtr<ISequentialOutStream
RINOK(Archive_Get_HardLinkNode(archive, index, h, defined));
if (defined)
{
- int linkIndex = _hardLinks.IDs.FindInSorted2(h);
- if (linkIndex >= 0)
+ const int linkIndex = _hardLinks.IDs.FindInSorted2(h);
+ if (linkIndex != -1)
{
FString &hl = _hardLinks.Links[(unsigned)linkIndex];
if (hl.IsEmpty())
@@ -1733,11 +1890,34 @@ HRESULT CArchiveExtractCallback::CloseFile()
_curSize = processedSize;
_curSizeDefined = true;
+ #if defined(_WIN32) && !defined(UNDER_CE) && !defined(_SFX)
+ if (ZoneBuf.Size() != 0
+ && !_item.IsAltStream)
+ {
+ // if (NFind::DoesFileExist_Raw(tempFilePath))
+ if (ZoneMode != NExtract::NZoneIdMode::kOffice ||
+ FindExt2(kOfficeExtensions, _diskFilePath))
+ {
+ // we must write zone file before setting of timestamps
+ const FString path = _diskFilePath + k_ZoneId_StreamName;
+ if (!WriteZoneFile(path, ZoneBuf))
+ {
+ // we can't write it in FAT
+ // SendMessageError_with_LastError("Can't write Zone.Identifier stream", path);
+ }
+ }
+ }
+ #endif
+
+ CFiTimesCAM t;
+ GetFiTimesCAM(t);
+
// #ifdef _WIN32
- _outFileStreamSpec->SetTime(
- (WriteCTime && _fi.CTimeDefined) ? &_fi.CTime : NULL,
- (WriteATime && _fi.ATimeDefined) ? &_fi.ATime : NULL,
- (WriteMTime && _fi.MTimeDefined) ? &_fi.MTime : (_arc->MTimeDefined ? &_arc->MTime : NULL));
+ 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());
@@ -2065,19 +2245,30 @@ HRESULT CArchiveExtractCallback::CloseReparseAndFile()
void CArchiveExtractCallback::SetAttrib()
{
- #ifndef _WIN32
+ #ifndef _WIN32
// Linux now doesn't support permissions for symlinks
if (_isSymLinkCreated)
return;
- #endif
+ #endif
if (_itemFailure
|| _diskFilePath.IsEmpty()
|| _stdOutMode
- || !_extractMode
- || !_fi.AttribDefined)
+ || !_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
+
+ if (_fi.Attrib_Defined)
{
// const AString s = GetAnsiString(_diskFilePath);
// printf("\nSetFileAttrib_PosixHighDetect: %s: hex:%x\n", s.Ptr(), _fi.Attrib);
@@ -2276,7 +2467,7 @@ STDMETHODIMP CArchiveExtractCallback::GetStream2(UInt32 index, ISequentialInStre
CInFileStream *inStreamSpec = new CInFileStream;
CMyComPtr<ISequentialInStream> inStreamRef = inStreamSpec;
- inStreamSpec->File.PreserveATime = _ntOptions.PreserveATime;
+ inStreamSpec->Set_PreserveATime(_ntOptions.PreserveATime);
if (!inStreamSpec->OpenShared(fullProcessedPath, _ntOptions.OpenShareForWrite))
{
RINOK(SendMessageError_with_LastError(kCantOpenInFile, fullProcessedPath));
@@ -2318,9 +2509,9 @@ void CDirPathSortPair::SetNumSlashes(const FChar *s)
bool CDirPathTime::SetDirTime() const
{
return NDir::SetDirTime(Path,
- CTimeDefined ? &CTime : NULL,
- ATimeDefined ? &ATime : NULL,
- MTimeDefined ? &MTime : NULL);
+ CTime_Defined ? &CTime : NULL,
+ ATime_Defined ? &ATime : NULL,
+ MTime_Defined ? &MTime : NULL);
}
diff --git a/CPP/7zip/UI/Common/ArchiveExtractCallback.h b/CPP/7zip/UI/Common/ArchiveExtractCallback.h
index fe9cb32e..fe70bc92 100644..100755
--- a/CPP/7zip/UI/Common/ArchiveExtractCallback.h
+++ b/CPP/7zip/UI/Common/ArchiveExtractCallback.h
@@ -60,6 +60,8 @@ struct CExtractNtOptions
bool ReplaceColonForAltStream;
bool WriteToAltStreamIfColon;
+ bool ExtractOwner;
+
bool PreAllocateOutFile;
// used for hash arcs only, when we open external files
@@ -69,6 +71,7 @@ struct CExtractNtOptions
CExtractNtOptions():
ReplaceColonForAltStream(false),
WriteToAltStreamIfColon(false),
+ ExtractOwner(false),
PreserveATime(false),
OpenShareForWrite(false)
{
@@ -163,16 +166,27 @@ struct CIndexToPathPair
-struct CDirPathTime
+struct CFiTimesCAM
{
- FILETIME CTime;
- FILETIME ATime;
- FILETIME MTime;
+ CFiTime CTime;
+ CFiTime ATime;
+ CFiTime MTime;
+
+ bool CTime_Defined;
+ bool ATime_Defined;
+ bool MTime_Defined;
- bool CTimeDefined;
- bool ATimeDefined;
- bool MTimeDefined;
+ bool IsSomeTimeDefined() const
+ {
+ return
+ CTime_Defined |
+ ATime_Defined |
+ MTime_Defined;
+ }
+};
+struct CDirPathTime: public CFiTimesCAM
+{
FString Path;
bool SetDirTime() const;
@@ -216,6 +230,25 @@ struct CLinkInfo
#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:
public IArchiveExtractCallback,
public IArchiveExtractCallbackMessage,
@@ -256,32 +289,33 @@ class CArchiveExtractCallback:
bool _extractMode;
- bool WriteCTime;
- bool WriteATime;
- bool WriteMTime;
+ bool Write_CTime;
+ bool Write_ATime;
+ bool Write_MTime;
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 (AttribDefined && (Attrib & FILE_ATTRIBUTE_REPARSE_POINT) != 0);
+ return (Attrib_Defined && (Attrib & FILE_ATTRIBUTE_REPARSE_POINT) != 0);
}
bool IsLinuxSymLink() const
{
- return (AttribDefined && MY_LIN_S_ISLNK(Attrib >> 16));
+ return (Attrib_Defined && MY_LIN_S_ISLNK(Attrib >> 16));
}
void SetFromPosixAttrib(UInt32 a)
@@ -294,10 +328,14 @@ class CArchiveExtractCallback:
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
- AttribDefined = true;
+ Attrib_Defined = true;
}
} _fi;
@@ -359,7 +397,7 @@ class CArchiveExtractCallback:
#endif
void CreateComplexDirectory(const UStringVector &dirPathParts, FString &fullPath);
- HRESULT GetTime(UInt32 index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined);
+ HRESULT GetTime(UInt32 index, PROPID propID, CArcTime &ft);
HRESULT GetUnpackSize();
FString Hash_GetFullFilePath();
@@ -372,6 +410,10 @@ public:
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;
@@ -405,11 +447,17 @@ public:
void InitForMulti(bool multiArchives,
NExtract::NPathMode::EEnum pathMode,
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;
}
@@ -427,6 +475,8 @@ public:
#endif
+ void InitBeforeNewArchive();
+
void Init(
const CExtractNtOptions &ntOptions,
const NWildcard::CCensorNode *wildcardCensor,
@@ -483,6 +533,7 @@ private:
HRESULT Read_fi_Props();
void CorrectPathParts();
+ void GetFiTimesCAM(CFiTimesCAM &pt);
void CreateFolders();
bool _isRenamed;
@@ -533,4 +584,6 @@ struct CArchiveExtractCallback_Closer
bool CensorNode_CheckPath(const NWildcard::CCensorNode &node, const CReadArcItem &item);
+void ReadZoneFile_Of_BaseFile(CFSTR fileName2, CByteBuffer &buf);
+
#endif
diff --git a/CPP/7zip/UI/Common/ArchiveName.cpp b/CPP/7zip/UI/Common/ArchiveName.cpp
index 1baf3e1e..1baf3e1e 100644..100755
--- a/CPP/7zip/UI/Common/ArchiveName.cpp
+++ b/CPP/7zip/UI/Common/ArchiveName.cpp
diff --git a/CPP/7zip/UI/Common/ArchiveName.h b/CPP/7zip/UI/Common/ArchiveName.h
index 0d32645f..0d32645f 100644..100755
--- a/CPP/7zip/UI/Common/ArchiveName.h
+++ b/CPP/7zip/UI/Common/ArchiveName.h
diff --git a/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp b/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp
index d5926f8f..64aa9878 100644..100755
--- a/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp
+++ b/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp
@@ -34,7 +34,8 @@ 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)
{
COM_TRY_BEGIN
@@ -51,10 +52,11 @@ STDMETHODIMP COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value)
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;
diff --git a/CPP/7zip/UI/Common/ArchiveOpenCallback.h b/CPP/7zip/UI/Common/ArchiveOpenCallback.h
index 46b26768..46b26768 100644..100755
--- a/CPP/7zip/UI/Common/ArchiveOpenCallback.h
+++ b/CPP/7zip/UI/Common/ArchiveOpenCallback.h
diff --git a/CPP/7zip/UI/Common/Bench.cpp b/CPP/7zip/UI/Common/Bench.cpp
index cc0cfd0c..cc0cfd0c 100644..100755
--- a/CPP/7zip/UI/Common/Bench.cpp
+++ b/CPP/7zip/UI/Common/Bench.cpp
diff --git a/CPP/7zip/UI/Common/Bench.h b/CPP/7zip/UI/Common/Bench.h
index ab0c3048..ab0c3048 100644..100755
--- a/CPP/7zip/UI/Common/Bench.h
+++ b/CPP/7zip/UI/Common/Bench.h
diff --git a/CPP/7zip/UI/Common/CompressCall.cpp b/CPP/7zip/UI/Common/CompressCall.cpp
index c7efa99e..3ef047f4 100644..100755
--- a/CPP/7zip/UI/Common/CompressCall.cpp
+++ b/CPP/7zip/UI/Common/CompressCall.cpp
@@ -252,7 +252,7 @@ static void ExtractGroupCommand(const UStringVector &arcPaths, UString &params,
ErrorMessageHRESULT(result);
}
-void ExtractArchives(const UStringVector &arcPaths, const UString &outFolder, bool showDialog, bool elimDup)
+void ExtractArchives(const UStringVector &arcPaths, const UString &outFolder, bool showDialog, bool elimDup, UInt32 writeZone)
{
MY_TRY_BEGIN
UString params ('x');
@@ -263,6 +263,11 @@ void ExtractArchives(const UStringVector &arcPaths, const UString &outFolder, bo
}
if (elimDup)
params += " -spe";
+ if (writeZone != (UInt32)(Int32)-1)
+ {
+ params += " -snz";
+ params.Add_UInt32(writeZone);
+ }
if (showDialog)
params += kShowDialogSwitch;
ExtractGroupCommand(arcPaths, params, false);
diff --git a/CPP/7zip/UI/Common/CompressCall.h b/CPP/7zip/UI/Common/CompressCall.h
index b817df0f..2697fda5 100644..100755
--- a/CPP/7zip/UI/Common/CompressCall.h
+++ b/CPP/7zip/UI/Common/CompressCall.h
@@ -15,7 +15,7 @@ HRESULT CompressFiles(
const UStringVector &names,
bool email, bool showDialog, bool waitFinish);
-void ExtractArchives(const UStringVector &arcPaths, const UString &outFolder, bool showDialog, bool elimDup);
+void ExtractArchives(const UStringVector &arcPaths, const UString &outFolder, bool showDialog, bool elimDup, UInt32 writeZone);
void TestArchives(const UStringVector &arcPaths, bool hashMode = false);
void CalcChecksum(const UStringVector &paths,
diff --git a/CPP/7zip/UI/Common/CompressCall2.cpp b/CPP/7zip/UI/Common/CompressCall2.cpp
index 762342d6..5d617e14 100644..100755
--- a/CPP/7zip/UI/Common/CompressCall2.cpp
+++ b/CPP/7zip/UI/Common/CompressCall2.cpp
@@ -152,19 +152,12 @@ HRESULT CompressFiles(
static HRESULT ExtractGroupCommand(const UStringVector &arcPaths,
- bool showDialog, const UString &outFolder, bool testMode, bool elimDup = false,
- const char *kType = NULL)
+ bool showDialog, CExtractOptions &eo, const char *kType = NULL)
{
MY_TRY_BEGIN
CREATE_CODECS
- CExtractOptions eo;
- eo.OutputDir = us2fs(outFolder);
- eo.TestMode = testMode;
- eo.ElimDup.Val = elimDup;
- eo.ElimDup.Def = elimDup;
-
CExtractCallbackImp *ecs = new CExtractCallbackImp;
CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs;
@@ -228,15 +221,26 @@ static HRESULT ExtractGroupCommand(const UStringVector &arcPaths,
return result;
}
-void ExtractArchives(const UStringVector &arcPaths, const UString &outFolder, bool showDialog, bool elimDup)
+void ExtractArchives(const UStringVector &arcPaths, const UString &outFolder,
+ bool showDialog, bool elimDup, UInt32 writeZone)
{
- ExtractGroupCommand(arcPaths, showDialog, outFolder, false, elimDup);
+ CExtractOptions eo;
+ eo.OutputDir = us2fs(outFolder);
+ eo.TestMode = false;
+ eo.ElimDup.Val = elimDup;
+ eo.ElimDup.Def = elimDup;
+ if (writeZone != (UInt32)(Int32)-1)
+ eo.ZoneMode = (NExtract::NZoneIdMode::EEnum)writeZone;
+ ExtractGroupCommand(arcPaths, showDialog, eo);
}
void TestArchives(const UStringVector &arcPaths, bool hashMode)
{
- ExtractGroupCommand(arcPaths, true, UString(), true,
- false, // elimDup
+ CExtractOptions eo;
+ eo.TestMode = true;
+ ExtractGroupCommand(arcPaths,
+ true, // showDialog
+ eo,
hashMode ? "hash" : NULL);
}
diff --git a/CPP/7zip/UI/Common/DefaultName.cpp b/CPP/7zip/UI/Common/DefaultName.cpp
index 8c34ffc7..8c34ffc7 100644..100755
--- a/CPP/7zip/UI/Common/DefaultName.cpp
+++ b/CPP/7zip/UI/Common/DefaultName.cpp
diff --git a/CPP/7zip/UI/Common/DefaultName.h b/CPP/7zip/UI/Common/DefaultName.h
index df164560..df164560 100644..100755
--- a/CPP/7zip/UI/Common/DefaultName.h
+++ b/CPP/7zip/UI/Common/DefaultName.h
diff --git a/CPP/7zip/UI/Common/DirItem.h b/CPP/7zip/UI/Common/DirItem.h
index e5f578dd..86e385fe 100644..100755
--- a/CPP/7zip/UI/Common/DirItem.h
+++ b/CPP/7zip/UI/Common/DirItem.h
@@ -10,6 +10,8 @@
#include "../../../Common/MyString.h"
#include "../../../Windows/FileFind.h"
+#include "../../../Windows/PropVariant.h"
+#include "../../../Windows/TimeUtils.h"
#include "../../Common/UniqBlocks.h"
@@ -80,50 +82,213 @@ struct IDirItemsCallback
INTERFACE_IDirItemsCallback(=0)
};
-struct CDirItem
+
+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;
- #ifndef UNDER_CE
+ #ifndef UNDER_CE
CByteBuffer ReparseData;
- #ifdef _WIN32
+ #ifdef _WIN32
// UString ShortName;
CByteBuffer ReparseData2; // fixed (reduced) absolute links for WIM format
bool AreReparseData() const { return ReparseData.Size() != 0 || ReparseData2.Size() != 0; }
- #else
+ #else
bool AreReparseData() const { return ReparseData.Size() != 0; }
- #endif // _WIN32
+ #endif // _WIN32
- #endif // !UNDER_CE
+ #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; }
- bool IsReadOnly() const { return (Attrib & FILE_ATTRIBUTE_READONLY) != 0; }
- bool Has_Attrib_ReparsePoint() const { return (Attrib & FILE_ATTRIBUTE_REPARSE_POINT) != 0; }
-
- #ifdef _WIN32
- UInt32 GetPosixAttrib() const
+ #ifdef _WIN32
+ #else
+ int OwnerNameIndex;
+ int OwnerGroupIndex;
+ #endif
+
+ CDirItem():
+ PhyParent(-1)
+ , LogParent(-1)
+ , SecureIndex(-1)
+ #ifdef _WIN32
+ #else
+ , OwnerNameIndex(-1)
+ , OwnerGroupIndex(-1)
+ #endif
{
- UInt32 v = IsDir() ? MY_LIN_S_IFDIR : MY_LIN_S_IFREG;
- /* 21.06: as WSL we allow write permissions (0222) for directories even for (FILE_ATTRIBUTE_READONLY).
- So extracting at Linux will be allowed to write files inside (0777) directories. */
- v |= ((IsReadOnly() && !IsDir()) ? 0555 : 0777);
- return v;
}
- #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
+ {}
};
@@ -145,6 +310,7 @@ public:
bool ScanAltStreams;
bool ExcludeDirItems;
bool ExcludeFileItems;
+ bool ShareForWrite;
/* it must be called after anotrher checks */
bool CanIncludeItem(bool isDir) const
@@ -160,7 +326,7 @@ public:
const FString &phyPrefix);
#endif
- #if defined(_WIN32) && !defined(UNDER_CE)
+ #if defined(_WIN32) && !defined(UNDER_CE)
CUniqBlocks SecureBlocks;
CByteBuffer TempSecureBuf;
@@ -170,7 +336,17 @@ public:
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;
@@ -204,20 +380,25 @@ public:
};
+
+
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/CPP/7zip/UI/Common/EnumDirItems.cpp b/CPP/7zip/UI/Common/EnumDirItems.cpp
index 89cce2ba..a4ac413f 100644..100755
--- a/CPP/7zip/UI/Common/EnumDirItems.cpp
+++ b/CPP/7zip/UI/Common/EnumDirItems.cpp
@@ -5,6 +5,12 @@
#include <wchar.h>
// #include <stdio.h>
+#ifndef _WIN32
+#include <grp.h>
+#include <pwd.h>
+#include "../../../Common/UTFConvert.h"
+#endif
+
#include "../../../Common/Wildcard.h"
#include "../../../Windows/FileDir.h"
@@ -23,32 +29,60 @@ 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++;
@@ -148,9 +182,13 @@ CDirItems::CDirItems():
ScanAltStreams(false)
, ExcludeDirItems(false)
, ExcludeFileItems(false)
- #ifdef _USE_SECURITY_CODE
+ , ShareForWrite(false)
+ #ifdef _USE_SECURITY_CODE
, ReadSecure(false)
- #endif
+ #endif
+ #ifndef _WIN32
+ , StoreOwnerName(true)
+ #endif
, Callback(NULL)
{
#ifdef _USE_SECURITY_CODE
@@ -379,7 +417,7 @@ HRESULT CDirItems::EnumerateItems2(
const FString &filePath = filePaths[i];
NFind::CFileInfo fi;
const FString phyPath = phyPrefix + filePath;
- if (!fi.Find(phyPath FOLLOW_LINK_PARAM))
+ if (!FindFile_KeepDots(fi, phyPath FOLLOW_LINK_PARAM))
{
RINOK(AddError(phyPath));
continue;
@@ -658,15 +696,14 @@ static HRESULT EnumerateForItem(
if (!enterToSubFolders)
return S_OK;
- #ifndef _WIN32
+ #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
}
- #endif
-
+ #else
if (dirItems.SymLinks && fi.HasReparsePoint())
{
/* 20.03: in SymLinks mode: we don't enter to directory that
@@ -677,6 +714,7 @@ static HRESULT EnumerateForItem(
*/
return S_OK;
}
+ #endif
nextNode = &curNode;
}
@@ -826,7 +864,7 @@ static HRESULT EnumerateDirItems(
}
else
#endif
- if (!fi.Find(fullPath FOLLOW_LINK_PARAM2))
+ if (!FindFile_KeepDots(fi, fullPath FOLLOW_LINK_PARAM2))
{
RINOK(dirItems.AddError(fullPath));
continue;
@@ -914,15 +952,14 @@ static HRESULT EnumerateDirItems(
}
else
{
- #ifndef _WIN32
+ #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
}
- #endif
-
+ #else
if (dirItems.SymLinks)
{
if (fi.HasReparsePoint())
@@ -932,6 +969,7 @@ static HRESULT EnumerateDirItems(
continue;
}
}
+ #endif
nextNode = &curNode;
newParts.Add(name); // don't change it to fi.Name. It's for shortnames support
}
@@ -973,7 +1011,7 @@ static HRESULT EnumerateDirItems(
}
else
{
- if (!fi.Find(fullPath FOLLOW_LINK_PARAM2))
+ if (!FindFile_KeepDots(fi, fullPath FOLLOW_LINK_PARAM2))
{
if (!nextNode.AreThereIncludeItems())
continue;
@@ -1136,15 +1174,18 @@ HRESULT EnumerateItems(
}
dirItems.ReserveDown();
- #if defined(_WIN32) && !defined(UNDER_CE)
+ #if defined(_WIN32) && !defined(UNDER_CE)
RINOK(dirItems.FillFixedReparse());
- #endif
+ #endif
+
+ #ifndef _WIN32
+ RINOK(dirItems.FillDeviceSizes());
+ #endif
return S_OK;
}
-
#if defined(_WIN32) && !defined(UNDER_CE)
HRESULT CDirItems::FillFixedReparse()
@@ -1281,6 +1322,148 @@ HRESULT CDirItems::FillFixedReparse()
#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]);
+ 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";
@@ -1351,11 +1534,18 @@ HRESULT EnumerateDirItemsAndSort(
#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))
+ if (name.IsEmpty()
+ || DoesNameContainWildcard(name)
+ || IsDotsName(name))
return;
NFind::CFileInfo fi;
const FString path (us2fs(prefix + name));
diff --git a/CPP/7zip/UI/Common/EnumDirItems.h b/CPP/7zip/UI/Common/EnumDirItems.h
index 9b17c600..9b17c600 100644..100755
--- a/CPP/7zip/UI/Common/EnumDirItems.h
+++ b/CPP/7zip/UI/Common/EnumDirItems.h
diff --git a/CPP/7zip/UI/Common/ExitCode.h b/CPP/7zip/UI/Common/ExitCode.h
index b6d7d4df..b6d7d4df 100644..100755
--- a/CPP/7zip/UI/Common/ExitCode.h
+++ b/CPP/7zip/UI/Common/ExitCode.h
diff --git a/CPP/7zip/UI/Common/Extract.cpp b/CPP/7zip/UI/Common/Extract.cpp
index de2aeb26..58f5218b 100644..100755
--- a/CPP/7zip/UI/Common/Extract.cpp
+++ b/CPP/7zip/UI/Common/Extract.cpp
@@ -239,18 +239,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 &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)
+ 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 (compare < 0)
+ if (comp < 0)
right = mid;
else
left = mid + 1;
@@ -314,8 +314,13 @@ HRESULT Extract(
CArchiveExtractCallback *ecs = new CArchiveExtractCallback;
CMyComPtr<IArchiveExtractCallback> ec(ecs);
- bool multi = (numArcs > 1);
- ecs->InitForMulti(multi, options.PathMode, options.OverwriteMode,
+
+ const bool multi = (numArcs > 1);
+
+ ecs->InitForMulti(multi,
+ options.PathMode,
+ options.OverwriteMode,
+ options.ZoneMode,
false // keepEmptyDirParts
);
#ifndef _SFX
@@ -335,12 +340,18 @@ 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
{
@@ -417,6 +428,15 @@ HRESULT Extract(
continue;
}
+ #if defined(_WIN32) && !defined(UNDER_CE) && !defined(_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))
@@ -490,11 +510,16 @@ HRESULT Extract(
*/
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 =
+ const bool calcCrc =
#ifndef _SFX
(hash != NULL);
#else
diff --git a/CPP/7zip/UI/Common/Extract.h b/CPP/7zip/UI/Common/Extract.h
index 10e06dad..f3d1126b 100644..100755
--- a/CPP/7zip/UI/Common/Extract.h
+++ b/CPP/7zip/UI/Common/Extract.h
@@ -25,6 +25,7 @@ struct CExtractOptionsBase
bool OverwriteMode_Force;
NExtract::NPathMode::EEnum PathMode;
NExtract::NOverwriteMode::EEnum OverwriteMode;
+ NExtract::NZoneIdMode::EEnum ZoneMode;
FString OutputDir;
CExtractNtOptions NtOptions;
@@ -36,7 +37,8 @@ struct CExtractOptionsBase
PathMode_Force(false),
OverwriteMode_Force(false),
PathMode(NExtract::NPathMode::kFullPaths),
- OverwriteMode(NExtract::NOverwriteMode::kAsk)
+ OverwriteMode(NExtract::NOverwriteMode::kAsk),
+ ZoneMode(NExtract::NZoneIdMode::kNone)
{}
};
diff --git a/CPP/7zip/UI/Common/ExtractMode.h b/CPP/7zip/UI/Common/ExtractMode.h
index 3b2b9a02..9ad831eb 100644..100755
--- a/CPP/7zip/UI/Common/ExtractMode.h
+++ b/CPP/7zip/UI/Common/ExtractMode.h
@@ -29,6 +29,16 @@ namespace NOverwriteMode
};
}
+namespace NZoneIdMode
+{
+ enum EEnum
+ {
+ kNone,
+ kAll,
+ kOffice
+ };
+}
+
}
#endif
diff --git a/CPP/7zip/UI/Common/ExtractingFilePath.cpp b/CPP/7zip/UI/Common/ExtractingFilePath.cpp
index 21a306d2..a1282b72 100644..100755
--- a/CPP/7zip/UI/Common/ExtractingFilePath.cpp
+++ b/CPP/7zip/UI/Common/ExtractingFilePath.cpp
@@ -34,10 +34,19 @@ static void ReplaceIncorrectChars(UString &s)
||
#endif
c == WCHAR_PATH_SEPARATOR)
+ {
+ #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,
- '_' // default
+ c
// (wchar_t)(0xf000 + c) // 21.02 debug: WSL encoding for unsupported characters
);
+ }
}
}
diff --git a/CPP/7zip/UI/Common/ExtractingFilePath.h b/CPP/7zip/UI/Common/ExtractingFilePath.h
index 8f8f9f1b..8f8f9f1b 100644..100755
--- a/CPP/7zip/UI/Common/ExtractingFilePath.h
+++ b/CPP/7zip/UI/Common/ExtractingFilePath.h
diff --git a/CPP/7zip/UI/Common/HashCalc.cpp b/CPP/7zip/UI/Common/HashCalc.cpp
index 24177085..f0aa4bd1 100644..100755
--- a/CPP/7zip/UI/Common/HashCalc.cpp
+++ b/CPP/7zip/UI/Common/HashCalc.cpp
@@ -15,6 +15,7 @@
#include "../../Common/StreamUtils.h"
#include "../../Archive/Common/ItemNameUtils.h"
+#include "../../Archive/IArchive.h"
#include "EnumDirItems.h"
#include "HashCalc.h"
@@ -309,8 +310,6 @@ static unsigned GetColumnWidth(unsigned digestSize)
}
-void HashHexToString(char *dest, const Byte *data, UInt32 size);
-
static void AddHashResultLine(
AString &_s,
// bool showHash,
@@ -463,10 +462,7 @@ 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
@@ -478,6 +474,8 @@ HRESULT HashCalc(
dirItems.ExcludeDirItems = censor.ExcludeDirItems;
dirItems.ExcludeFileItems = censor.ExcludeFileItems;
+ dirItems.ShareForWrite = options.OpenShareForWrite;
+
HRESULT res = EnumerateItems(censor,
options.PathMode,
UString(),
@@ -498,14 +496,16 @@ HRESULT HashCalc(
// hb.Init();
hb.NumErrors = dirItems.Stat.NumErrors;
-
+
+ UInt64 totalSize = 0;
if (options.StdInMode)
{
RINOK(callback->SetNumFiles(1));
}
else
{
- RINOK(callback->SetTotal(dirItems.Stat.GetTotalBytes()));
+ totalSize = dirItems.Stat.GetTotalBytes();
+ RINOK(callback->SetTotal(totalSize));
}
const UInt32 kBufSize = 1 << 15;
@@ -537,7 +537,9 @@ HRESULT HashCalc(
{
path = dirItems.GetLogPath(i);
const CDirItem &di = dirItems.Items[i];
+ #ifdef _WIN32
isAltStream = di.IsAltStream;
+ #endif
#ifndef UNDER_CE
// if (di.AreReparseData())
@@ -551,7 +553,7 @@ HRESULT HashCalc(
#endif
{
CInFileStream *inStreamSpec = new CInFileStream;
- inStreamSpec->File.PreserveATime = options.PreserveATime;
+ inStreamSpec->Set_PreserveATime(options.PreserveATime);
inStream = inStreamSpec;
isDir = di.IsDir();
if (!isDir)
@@ -565,6 +567,20 @@ HRESULT HashCalc(
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();
}
}
}
@@ -580,6 +596,7 @@ HRESULT HashCalc(
{
if ((step & 0xFF) == 0)
{
+ // printf("\ncompl = %d\n", (unsigned)(completeValue >> 20));
RINOK(callback->SetCompleted(&completeValue));
}
UInt32 size;
@@ -1679,8 +1696,11 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (_isArc && !CanUpdate())
return E_NOTIMPL;
- // const UINT codePage = CP_UTF8; // // (_forceCodePage ? _specifiedCodePage : _openCodePage);
- // const unsigned utfFlags = g_Unicode_To_UTF8_Flags;
+ /*
+ CMyComPtr<IArchiveUpdateCallbackArcProp> reportArcProp;
+ callback->QueryInterface(IID_IArchiveUpdateCallbackArcProp, (void **)&reportArcProp);
+ */
+
CObjectVector<CUpdateItem> updateItems;
UInt64 complexity = 0;
@@ -1827,6 +1847,8 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (ui.NewData)
{
UInt64 currentComplexity = ui.Size;
+ UInt64 fileSize = 0;
+
CMyComPtr<ISequentialInStream> fileInStream;
bool needWrite = true;
{
@@ -1840,6 +1862,15 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (fileInStream)
{
+ CMyComPtr<IStreamGetSize> streamGetSize;
+ fileInStream->QueryInterface(IID_IStreamGetSize, (void **)&streamGetSize);
+ if (streamGetSize)
+ {
+ UInt64 size;
+ if (streamGetSize->GetSize(&size) == S_OK)
+ currentComplexity = size;
+ }
+ /*
CMyComPtr<IStreamGetProps> getProps;
fileInStream->QueryInterface(IID_IStreamGetProps, (void **)&getProps);
if (getProps)
@@ -1852,6 +1883,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
// item.MTime = NWindows::NTime::FileTimeToUnixTime64(mTime);;
}
}
+ */
}
else
{
@@ -1865,7 +1897,6 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (needWrite && fileInStream && !isDir)
{
- UInt64 fileSize = 0;
for (UInt32 step = 0;; step++)
{
if ((step & 0xFF) == 0)
@@ -1901,6 +1932,36 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
}
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
diff --git a/CPP/7zip/UI/Common/HashCalc.h b/CPP/7zip/UI/Common/HashCalc.h
index 80a55653..c566caa8 100644..100755
--- a/CPP/7zip/UI/Common/HashCalc.h
+++ b/CPP/7zip/UI/Common/HashCalc.h
@@ -16,6 +16,12 @@ 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,
diff --git a/CPP/7zip/UI/Common/IFileExtractCallback.h b/CPP/7zip/UI/Common/IFileExtractCallback.h
index e6a85c6d..e6a85c6d 100644..100755
--- a/CPP/7zip/UI/Common/IFileExtractCallback.h
+++ b/CPP/7zip/UI/Common/IFileExtractCallback.h
diff --git a/CPP/7zip/UI/Common/LoadCodecs.cpp b/CPP/7zip/UI/Common/LoadCodecs.cpp
index 377963aa..b6a20732 100644..100755
--- a/CPP/7zip/UI/Common/LoadCodecs.cpp
+++ b/CPP/7zip/UI/Common/LoadCodecs.cpp
@@ -33,8 +33,6 @@ EXPORT_CODECS
#include "StdAfx.h"
-#include "../../../../C/7zVersion.h"
-
#include "../../../Common/MyCom.h"
#include "../../../Common/StringToInt.h"
#include "../../../Common/StringConvert.h"
@@ -275,6 +273,9 @@ static HRESULT GetMethodBoolProp(Func_GetMethodProperty getMethodProperty, UInt3
#define MY_GET_FUNC(dest, type, func) *(void **)(&dest) = (func);
// #define MY_GET_FUNC(dest, type, func) dest = (type)(func);
+#define MY_GET_FUNC_LOC(dest, type, func) \
+ type dest; MY_GET_FUNC(dest, type, func)
+
HRESULT CCodecs::LoadCodecs()
{
CCodecLib &lib = Libs.Back();
@@ -286,8 +287,7 @@ HRESULT CCodecs::LoadCodecs()
if (lib.GetMethodProperty)
{
UInt32 numMethods = 1;
- Func_GetNumberOfMethods getNumberOfMethods;
- MY_GET_FUNC (getNumberOfMethods, Func_GetNumberOfMethods, lib.Lib.GetProc("GetNumberOfMethods"));
+ MY_GET_FUNC_LOC (getNumberOfMethods, Func_GetNumberOfMethods, lib.Lib.GetProc("GetNumberOfMethods"));
if (getNumberOfMethods)
{
RINOK(getNumberOfMethods(&numMethods));
@@ -304,8 +304,7 @@ HRESULT CCodecs::LoadCodecs()
}
}
- Func_GetHashers getHashers;
- MY_GET_FUNC (getHashers, Func_GetHashers, lib.Lib.GetProc("GetHashers"));
+ MY_GET_FUNC_LOC (getHashers, Func_GetHashers, lib.Lib.GetProc("GetHashers"));
if (getHashers)
{
RINOK(getHashers(&lib.ComHashers));
@@ -414,17 +413,14 @@ HRESULT CCodecs::LoadFormats()
const NDLL::CLibrary &lib = Libs.Back().Lib;
Func_GetHandlerProperty getProp = NULL;
- Func_GetHandlerProperty2 getProp2;
- MY_GET_FUNC (getProp2, Func_GetHandlerProperty2, lib.GetProc("GetHandlerProperty2"));
- Func_GetIsArc getIsArc;
- MY_GET_FUNC (getIsArc, Func_GetIsArc, lib.GetProc("GetIsArc"));
+ MY_GET_FUNC_LOC (getProp2, Func_GetHandlerProperty2, lib.GetProc("GetHandlerProperty2"));
+ MY_GET_FUNC_LOC (getIsArc, Func_GetIsArc, lib.GetProc("GetIsArc"));
UInt32 numFormats = 1;
if (getProp2)
{
- Func_GetNumberOfFormats getNumberOfFormats;
- MY_GET_FUNC (getNumberOfFormats, Func_GetNumberOfFormats, lib.GetProc("GetNumberOfFormats"));
+ MY_GET_FUNC_LOC (getNumberOfFormats, Func_GetNumberOfFormats, lib.GetProc("GetNumberOfFormats"));
if (getNumberOfFormats)
{
RINOK(getNumberOfFormats(&numFormats));
@@ -477,6 +473,11 @@ 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));
@@ -567,8 +568,7 @@ HRESULT CCodecs::LoadDll(const FString &dllPath, bool needCheckDll, bool *loaded
/*
{
- Func_LibStartup _LibStartup;
- MY_GET_FUNC (_LibStartup, Func_LibStartup, lib.Lib.GetProc("LibStartup"));
+ MY_GET_FUNC_LOC (_LibStartup, Func_LibStartup, lib.Lib.GetProc("LibStartup"));
if (_LibStartup)
{
HRESULT res = _LibStartup();
@@ -585,21 +585,31 @@ HRESULT CCodecs::LoadDll(const FString &dllPath, bool needCheckDll, bool *loaded
#ifdef _7ZIP_LARGE_PAGES
if (g_LargePageSize != 0)
{
- Func_SetLargePageMode setLargePageMode;
- MY_GET_FUNC (setLargePageMode, Func_SetLargePageMode, lib.Lib.GetProc("SetLargePageMode"));
+ MY_GET_FUNC_LOC (setLargePageMode, Func_SetLargePageMode, lib.Lib.GetProc("SetLargePageMode"));
if (setLargePageMode)
setLargePageMode();
}
#endif
- if (CaseSensitiveChange)
+ if (CaseSensitive_Change)
{
- Func_SetCaseSensitive setCaseSensitive;
- MY_GET_FUNC (setCaseSensitive, Func_SetCaseSensitive, lib.Lib.GetProc("SetCaseSensitive"));
+ MY_GET_FUNC_LOC (setCaseSensitive, Func_SetCaseSensitive, lib.Lib.GetProc("SetCaseSensitive"));
if (setCaseSensitive)
setCaseSensitive(CaseSensitive ? 1 : 0);
}
+ /*
+ {
+ MY_GET_FUNC_LOC (setClientVersion, Func_SetClientVersion, lib.Lib.GetProc("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.GetProc("CreateObject"));
{
unsigned startSize = Codecs.Size() + Hashers.Size();
diff --git a/CPP/7zip/UI/Common/LoadCodecs.h b/CPP/7zip/UI/Common/LoadCodecs.h
index 829472d0..50fb9f8f 100644..100755
--- a/CPP/7zip/UI/Common/LoadCodecs.h
+++ b/CPP/7zip/UI/Common/LoadCodecs.h
@@ -96,6 +96,7 @@ struct CArcExtInfo
struct CArcInfoEx
{
UInt32 Flags;
+ UInt32 TimeFlags;
Func_CreateInArchive CreateInArchive;
Func_IsArc IsArcFunc;
@@ -142,7 +143,7 @@ struct CArcInfoEx
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; }
@@ -154,6 +155,27 @@ struct CArcInfoEx
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())
@@ -162,6 +184,15 @@ 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"); }
+
/*
UString GetAllExtensions() const
{
@@ -178,11 +209,10 @@ 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
@@ -333,14 +363,14 @@ public:
CRecordVector<CDllHasherInfo> Hashers;
#endif
- bool CaseSensitiveChange;
+ bool CaseSensitive_Change;
bool CaseSensitive;
CCodecs():
#ifdef EXTERNAL_CODECS
NeedSetLibCodecs(true),
#endif
- CaseSensitiveChange(false),
+ CaseSensitive_Change(false),
CaseSensitive(false)
{}
diff --git a/CPP/7zip/UI/Common/OpenArchive.cpp b/CPP/7zip/UI/Common/OpenArchive.cpp
index 331793f1..4a91a268 100644..100755
--- a/CPP/7zip/UI/Common/OpenArchive.cpp
+++ b/CPP/7zip/UI/Common/OpenArchive.cpp
@@ -209,8 +209,8 @@ 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)
@@ -262,8 +262,8 @@ 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((unsigned)pos, item);
UInt64 next = item.Offset + item.Size;
@@ -482,7 +482,7 @@ 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;
@@ -532,7 +532,7 @@ static HRESULT Archive_GetArcProp_Int(IInArchive *arc, PROPID propid, Int64 &res
#ifndef _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;
@@ -616,7 +616,7 @@ HRESULT CArc::GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &pa
-HRESULT CArc::GetItemPath(UInt32 index, UString &result) const
+HRESULT CArc::GetItem_Path(UInt32 index, UString &result) const
{
#ifdef MY_CPU_LE
if (GetRawProps)
@@ -752,13 +752,13 @@ 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;
@@ -779,9 +779,9 @@ 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;
@@ -833,7 +833,7 @@ HRESULT CArc::GetItem(UInt32 index, CReadArcItem &item) const
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
UInt32 mainIndex = index;
@@ -885,7 +885,7 @@ HRESULT CArc::GetItem(UInt32 index, CReadArcItem &item) const
}
else
{
- RINOK(GetItemPath2(parentIndex, item.MainPath));
+ RINOK(GetItem_Path2(parentIndex, item.MainPath));
RINOK(Archive_IsItem_Dir(Archive, parentIndex, item.MainIsDir));
}
}
@@ -911,7 +911,7 @@ HRESULT CArc::GetItem(UInt32 index, CReadArcItem &item) const
#ifndef _SFX
if (item._use_baseParentFolder_mode)
{
- RINOK(GetItemPathToParent(mainIndex, (unsigned)item._baseParentFolder, item.PathParts));
+ RINOK(GetItem_PathToParent(mainIndex, (unsigned)item._baseParentFolder, item.PathParts));
#ifdef SUPPORT_ALT_STREAMS
if ((item.WriteToAltStreamIfColon || needFindAltStream) && !item.PathParts.IsEmpty())
@@ -970,7 +970,7 @@ 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;
@@ -989,24 +989,52 @@ 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));
+
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;
}
@@ -1020,6 +1048,7 @@ 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)
@@ -1034,7 +1063,7 @@ static void MakeCheckOrder(CCodecs *codecs,
{
if (ai.Signatures.IsEmpty())
{
- if (dataSize != 0) // 21.04: no Sinature means Empty Signature
+ if (dataSize != 0) // 21.04: no Signature means Empty Signature
continue;
}
else
@@ -1229,7 +1258,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;
@@ -1262,12 +1291,12 @@ HRESULT CArc::ReadBasicProps(IInArchive *archive, UInt64 startPos, HRESULT openR
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;
}
*/
@@ -1277,7 +1306,7 @@ HRESULT CArc::ReadBasicProps(IInArchive *archive, UInt64 startPos, HRESULT openR
Int64 globalOffset = (Int64)startPos + Offset;
AvailPhySize = (UInt64)((Int64)FileSize - globalOffset);
- if (PhySizeDefined)
+ if (PhySize_Defined)
{
UInt64 endPos = (UInt64)(globalOffset + (Int64)PhySize);
if (endPos < FileSize)
@@ -1378,9 +1407,9 @@ 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();
{
@@ -1584,7 +1613,7 @@ static HRESULT OpenArchiveSpec(IInArchive *archive, bool needPhySize,
return S_OK;
bool phySizeCantBeDetected = false;
- RINOK(Archive_GetArcBoolProp(archive, kpidPhySizeCantBeDetected, phySizeCantBeDetected));
+ RINOK(Archive_GetArcProp_Bool(archive, kpidPhySizeCantBeDetected, phySizeCantBeDetected));
if (!phySizeCantBeDetected)
{
@@ -1724,7 +1753,7 @@ 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((int)i) >= 0)
continue;
@@ -1736,8 +1765,8 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
if (ai.FindExtension(extension) >= 0
#ifndef _SFX
- || (isZip && StringsAreEqualNoCase_Ascii(ai.Name, "zip"))
- || (isRar && StringsAreEqualNoCase_Ascii(ai.Name, "rar"))
+ || (isZip && ai.Is_Zip())
+ || (isRar && ai.Is_Rar())
#endif
)
{
@@ -1811,11 +1840,27 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
/*
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);
@@ -1906,6 +1951,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
// OutputDebugStringW(ai.Name);
if (i >= numMainTypes)
{
+ // here we allow mismatched extension only for backward handlers
if (!ai.Flags_BackwardOpen()
// && !ai.Flags_PureStartOpen()
)
@@ -2125,7 +2171,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
const CArcInfoEx &ai = op.codecs->Formats[form];
- if (ai.IsSplit())
+ if (ai.Is_Split())
{
splitIndex = (int)form;
continue;
@@ -2234,7 +2280,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
// bool needScan = false;
- if (!PhySizeDefined)
+ if (!PhySize_Defined)
{
// it's for Z format
pi.LenIsUnknown = true;
@@ -2726,14 +2772,14 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
}
continue;
}
- if (!ErrorInfo.IsArc_After_NonOpen() || !PhySizeDefined || PhySize == 0)
+ if (!ErrorInfo.IsArc_After_NonOpen() || !PhySize_Defined || PhySize == 0)
continue;
}
else
{
- if (PhySizeDefined && PhySize == 0)
+ if (PhySize_Defined && PhySize == 0)
{
- PRF(printf(" phySizeDefined && PhySize == 0 "));
+ PRF(printf(" phySize_Defined && PhySize == 0 "));
// we skip that epmty archive case with unusual unexpected (PhySize == 0) from Code function.
continue;
}
@@ -2754,10 +2800,10 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
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)
{
@@ -2783,7 +2829,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
bool needScan = false;
- if (isOpen && !phySizeDefined)
+ if (isOpen && !phySize_Defined)
{
// it's for Z format, or bzip2,gz,xz with phySize that was not detected
pi.LenIsUnknown = true;
@@ -2802,7 +2848,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)
@@ -2830,7 +2876,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
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 */
@@ -2849,7 +2895,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;
@@ -2993,12 +3039,12 @@ 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;
@@ -3092,7 +3138,7 @@ 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 += '.';
@@ -3299,7 +3345,7 @@ 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));
@@ -3343,7 +3389,7 @@ HRESULT CArchiveLink::Open(COpenOptions &op)
break;
}
RINOK(result);
- RINOK(arc.GetItemMTime(mainSubfile, arc2.MTime, arc2.MTimeDefined));
+ RINOK(arc.GetItem_MTime(mainSubfile, arc2.MTime));
Arcs.Add(arc2);
}
IsOpen = !Arcs.IsEmpty();
diff --git a/CPP/7zip/UI/Common/OpenArchive.h b/CPP/7zip/UI/Common/OpenArchive.h
index 4e1192cf..e3220b94 100644..100755
--- a/CPP/7zip/UI/Common/OpenArchive.h
+++ b/CPP/7zip/UI/Common/OpenArchive.h
@@ -8,6 +8,7 @@
#include "ArchiveOpenCallback.h"
#include "LoadCodecs.h"
#include "Property.h"
+#include "DirItem.h"
#ifndef _SFX
@@ -260,6 +261,9 @@ struct CReadArcItem
}
};
+
+
+
class CArc
{
HRESULT PrepareToOpen(const COpenOptions &op, unsigned formatIndex, CMyComPtr<IInArchive> &archive);
@@ -268,7 +272,7 @@ class CArc
#ifndef _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:
@@ -289,19 +293,21 @@ public:
UString DefaultName;
int FormatIndex; // -1 means Parser
UInt32 SubfileIndex; // (UInt32)(Int32)-1; means no subfile
- FILETIME MTime;
- bool MTimeDefined;
+
+ // 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; }
+ UInt64 GetEstmatedPhySize() const { return PhySize_Defined ? PhySize : FileSize; }
UInt64 ArcStreamOffset; // offset of stream that is open by Archive Handler
Int64 GetGlobalOffset() const { return (Int64)ArcStreamOffset + Offset; } // it's global offset of archive
@@ -323,7 +329,7 @@ public:
// void Set_ErrorFlagsText();
CArc():
- MTimeDefined(false),
+ // MTime_Defined(false),
IsTree(false),
IsReadOnly(false),
Ask_Deleted(false),
@@ -343,17 +349,29 @@ public:
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); }
diff --git a/CPP/7zip/UI/Common/PropIDUtils.cpp b/CPP/7zip/UI/Common/PropIDUtils.cpp
index 30efd53b..72384b3e 100644..100755
--- a/CPP/7zip/UI/Common/PropIDUtils.cpp
+++ b/CPP/7zip/UI/Common/PropIDUtils.cpp
@@ -136,10 +136,37 @@ void ConvertPropertyToShortString2(char *dest, const PROPVARIANT &prop, PROPID p
if (prop.vt == VT_FILETIME)
{
const FILETIME &ft = prop.filetime;
- if ((ft.dwHighDateTime == 0 &&
- ft.dwLowDateTime == 0))
+ 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;
- ConvertUtcFileTimeToString(prop.filetime, dest, level);
+ if (level > numDigits)
+ level = numDigits;
+ ConvertUtcFileTimeToString2(ft, ns100, dest, level);
return;
}
@@ -198,6 +225,24 @@ void ConvertPropertyToShortString2(char *dest, const PROPVARIANT &prop, PROPID p
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);
diff --git a/CPP/7zip/UI/Common/PropIDUtils.h b/CPP/7zip/UI/Common/PropIDUtils.h
index 915bfc28..915bfc28 100644..100755
--- a/CPP/7zip/UI/Common/PropIDUtils.h
+++ b/CPP/7zip/UI/Common/PropIDUtils.h
diff --git a/CPP/7zip/UI/Common/Property.h b/CPP/7zip/UI/Common/Property.h
index 8b57a2a6..8b57a2a6 100644..100755
--- a/CPP/7zip/UI/Common/Property.h
+++ b/CPP/7zip/UI/Common/Property.h
diff --git a/CPP/7zip/UI/Common/SetProperties.cpp b/CPP/7zip/UI/Common/SetProperties.cpp
index 4b3037af..4b3037af 100644..100755
--- a/CPP/7zip/UI/Common/SetProperties.cpp
+++ b/CPP/7zip/UI/Common/SetProperties.cpp
diff --git a/CPP/7zip/UI/Common/SetProperties.h b/CPP/7zip/UI/Common/SetProperties.h
index 892f1a21..892f1a21 100644..100755
--- a/CPP/7zip/UI/Common/SetProperties.h
+++ b/CPP/7zip/UI/Common/SetProperties.h
diff --git a/CPP/7zip/UI/Common/SortUtils.cpp b/CPP/7zip/UI/Common/SortUtils.cpp
index 5f29249b..5f29249b 100644..100755
--- a/CPP/7zip/UI/Common/SortUtils.cpp
+++ b/CPP/7zip/UI/Common/SortUtils.cpp
diff --git a/CPP/7zip/UI/Common/SortUtils.h b/CPP/7zip/UI/Common/SortUtils.h
index 8e42e068..8e42e068 100644..100755
--- a/CPP/7zip/UI/Common/SortUtils.h
+++ b/CPP/7zip/UI/Common/SortUtils.h
diff --git a/CPP/7zip/UI/Common/StdAfx.h b/CPP/7zip/UI/Common/StdAfx.h
index 2854ff3e..2854ff3e 100644..100755
--- a/CPP/7zip/UI/Common/StdAfx.h
+++ b/CPP/7zip/UI/Common/StdAfx.h
diff --git a/CPP/7zip/UI/Common/TempFiles.cpp b/CPP/7zip/UI/Common/TempFiles.cpp
index 2f868381..2f868381 100644..100755
--- a/CPP/7zip/UI/Common/TempFiles.cpp
+++ b/CPP/7zip/UI/Common/TempFiles.cpp
diff --git a/CPP/7zip/UI/Common/TempFiles.h b/CPP/7zip/UI/Common/TempFiles.h
index 4099e655..4099e655 100644..100755
--- a/CPP/7zip/UI/Common/TempFiles.h
+++ b/CPP/7zip/UI/Common/TempFiles.h
diff --git a/CPP/7zip/UI/Common/Update.cpp b/CPP/7zip/UI/Common/Update.cpp
index 032a876d..042991d1 100644..100755
--- a/CPP/7zip/UI/Common/Update.cpp
+++ b/CPP/7zip/UI/Common/Update.cpp
@@ -2,6 +2,8 @@
#include "StdAfx.h"
+// #include <stdio.h>
+
#include "Update.h"
#include "../../../Common/StringConvert.h"
@@ -101,7 +103,7 @@ public:
_length = 0;
}
- bool SetMTime(const FILETIME *mTime);
+ bool SetMTime(const CFiTime *mTime);
HRESULT Close();
UInt64 GetSize() const { return _length; }
@@ -131,7 +133,7 @@ HRESULT COutMultiVolStream::Close()
return res;
}
-bool COutMultiVolStream::SetMTime(const FILETIME *mTime)
+bool COutMultiVolStream::SetMTime(const CFiTime *mTime)
{
bool res = true;
FOR_VECTOR (i, Streams)
@@ -545,11 +547,46 @@ static HRESULT Compress(
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));
+
+ // we support any future fileType here.
+ fileTimeType = (NFileTimeType::EEnum)value;
+ /*
+ old 21.07 code:
switch (value)
{
case NFileTimeType::kWindows:
@@ -560,13 +597,26 @@ static HRESULT Compress(
default:
return E_FAIL;
}
+ */
}
+ // bool noTimestampExpected = false;
{
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;
@@ -626,7 +676,7 @@ static HRESULT Compress(
if (needRename)
{
up2.NewProps = true;
- RINOK(arc->IsItemAnti(i, up2.IsAnti));
+ RINOK(arc->IsItem_Anti(i, up2.IsAnti));
up2.NewNameIndex = (int)newNames.Add(dest);
}
updatePairs2.Add(up2);
@@ -661,6 +711,7 @@ static HRESULT Compress(
else
stat.NumDirs++;
}
+ #ifdef _WIN32
else if (di.IsAltStream)
{
if (up.IsAnti)
@@ -671,6 +722,7 @@ static HRESULT Compress(
stat.AltStreamsSize += di.Size;
}
}
+ #endif
else
{
if (up.IsAnti)
@@ -740,6 +792,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;
@@ -755,6 +809,12 @@ static HRESULT Compress(
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;
@@ -838,8 +898,6 @@ static HRESULT Compress(
*/
}
- RINOK(SetProperties(outArchive, options.MethodMode.Properties));
-
if (options.SfxMode)
{
CInFileStream *sfxStreamSpec = new CInFileStream;
@@ -909,24 +967,71 @@ static HRESULT Compress(
if (options.SetArcMTime)
{
- FILETIME ft;
- ft.dwLowDateTime = 0;
- ft.dwHighDateTime = 0;
- FOR_VECTOR (i, updatePairs2)
+ CFiTime ft;
+ FiTime_Clear(ft);
+ bool isDefined = false;
+
+ // bool needNormalizeAfterStream;
+ // needParse;
+ /*
+ if (updateCallbackSpec->ArcMTime_WasReported)
{
- const CUpdatePair2 &pair2 = updatePairs2[i];
- const FILETIME *ft2 = NULL;
- if (pair2.NewProps && pair2.DirIndex >= 0)
- ft2 = &dirItems.Items[(unsigned)pair2.DirIndex].MTime;
- else if (pair2.UseArcProps && pair2.ArcIndex >= 0)
- ft2 = &arcItems[(unsigned)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;
+ ft = updateCallbackSpec->LatestMTime;
+ isDefined = true;
}
+
+ FOR_VECTOR (i, updatePairs2)
+ {
+ const CUpdatePair2 &pair2 = updatePairs2[i];
+ CFiTime 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 (Compare_FiTime(&ft, &ft2) < 0)
+ {
+ ft = ft2;
+ isDefined = 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 (isDefined)
{
if (outStreamSpec)
outStreamSpec->SetMTime(&ft);
@@ -1046,26 +1151,9 @@ static HRESULT EnumerateInArchiveItems(
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);
@@ -1198,8 +1286,10 @@ HRESULT UpdateArchive(
EISDIR
#endif
);
+ #ifdef _WIN32
if (fi.IsDevice)
return E_NOTIMPL;
+ #endif
if (!options.StdOutMode && options.UpdateArchiveItself)
if (fi.IsReadOnly())
@@ -1262,8 +1352,14 @@ HRESULT UpdateArchive(
}
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)
{
@@ -1307,10 +1403,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);
}
@@ -1336,8 +1433,14 @@ HRESULT UpdateArchive(
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,
UString(), // options.AddPathPrefix,
dirItems);
@@ -1351,6 +1454,8 @@ HRESULT UpdateArchive(
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;
@@ -1366,11 +1471,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;
@@ -1723,8 +1824,8 @@ HRESULT UpdateArchive(
is_SameSize = (fileInfo.Size == dirItem.Size);
if (is_SameSize
- && CompareFileTime(&fileInfo.MTime, &dirItem.MTime) == 0
- && CompareFileTime(&fileInfo.CTime, &dirItem.CTime) == 0)
+ && Compare_FiTime(&fileInfo.MTime, &dirItem.MTime) == 0
+ && Compare_FiTime(&fileInfo.CTime, &dirItem.CTime) == 0)
{
RINOK(callback->DeletingAfterArchiving(phyPath, false));
DeleteFileAlways(phyPath);
diff --git a/CPP/7zip/UI/Common/Update.h b/CPP/7zip/UI/Common/Update.h
index 06d13877..01fc43e2 100644..100755
--- a/CPP/7zip/UI/Common/Update.h
+++ b/CPP/7zip/UI/Common/Update.h
@@ -112,6 +112,9 @@ struct CUpdateOptions
CBoolPair HardLinks;
CBoolPair SymLinks;
+ CBoolPair StoreOwnerId;
+ CBoolPair StoreOwnerName;
+
bool DeleteAfterCompressing;
bool SetArcMTime;
diff --git a/CPP/7zip/UI/Common/UpdateAction.cpp b/CPP/7zip/UI/Common/UpdateAction.cpp
index a80db721..a80db721 100644..100755
--- a/CPP/7zip/UI/Common/UpdateAction.cpp
+++ b/CPP/7zip/UI/Common/UpdateAction.cpp
diff --git a/CPP/7zip/UI/Common/UpdateAction.h b/CPP/7zip/UI/Common/UpdateAction.h
index bc53fcdb..bc53fcdb 100644..100755
--- a/CPP/7zip/UI/Common/UpdateAction.h
+++ b/CPP/7zip/UI/Common/UpdateAction.h
diff --git a/CPP/7zip/UI/Common/UpdateCallback.cpp b/CPP/7zip/UI/Common/UpdateCallback.cpp
index 7b705ba3..926a275d 100644..100755
--- a/CPP/7zip/UI/Common/UpdateCallback.cpp
+++ b/CPP/7zip/UI/Common/UpdateCallback.cpp
@@ -4,6 +4,15 @@
// #include <stdio.h>
+#ifndef _WIN32
+// #include <grp.h>
+// #include <pwd.h>
+
+// for major minor:
+// BSD: <sys/types.h>
+#include <sys/sysmacros.h>
+#endif
+
#ifndef _7ZIP_ST
#include "../../../Windows/Synchronization.h"
#endif
@@ -66,6 +75,18 @@ CArchiveUpdateCallback::CArchiveUpdateCallback():
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),
ProcessedItemsStatuses(NULL)
{
@@ -134,16 +155,17 @@ STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 index,
COM_TRY_END
}
+
STDMETHODIMP 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);
@@ -446,25 +468,46 @@ STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PR
{
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
- case kpidPosixAttrib:
- {
- #ifdef _WIN32
- prop = di.GetPosixAttrib();
- #else
- if (di.Attrib & FILE_ATTRIBUTE_UNIX_EXTENSION)
- prop = (UInt32)(di.Attrib >> 16);
- #endif
+ #else
+
+ 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;
+
+ // 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);
@@ -565,12 +608,41 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStrea
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->File.PreserveATime = PreserveATime;
+ inStreamSpec->Set_PreserveATime(PreserveATime
+ || mode == NUpdateNotifyOp::kAnalyze); // 22.00 : we don't change access time in Analyze pass.
const FString path = DirItems->GetPhyPath((unsigned)up.DirIndex);
_openFiles_Indexes.Add(index);
_openFiles_Paths.Add(path);
+ // _openFiles_Streams.Add(inStreamSpec);
/* 21.02 : we set Callback/CallbackRef after _openFiles_Indexes adding
for correct working if exception was raised in GetPhyPath */
@@ -579,14 +651,30 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStrea
if (!inStreamSpec->OpenShared(path, ShareForWrite))
{
- DWORD error = ::GetLastError();
- HRESULT hres = Callback->OpenFileError(path, error);
+ const DWORD error = ::GetLastError();
+ const HRESULT hres = Callback->OpenFileError(path, error);
if (StopAfterOpenError)
if (hres == S_OK || hres == S_FALSE)
return HRESULT_FROM_WIN32(error);
return hres;
}
+ /*
+ {
+ // for debug:
+ Byte b = 0;
+ UInt32 processedSize = 0;
+ if (inStreamSpec->Read(&b, 1, &processedSize) != S_OK ||
+ processedSize != 1)
+ return E_FAIL;
+ }
+ */
+
+ if (Need_LatestMTime)
+ {
+ inStreamSpec->ReloadProps();
+ }
+
// #if defined(USE_WIN_FILE) || !defined(_WIN32)
if (StoreHardLinks)
{
@@ -643,6 +731,8 @@ STDMETHODIMP CArchiveUpdateCallback::ReportOperation(UInt32 indexType, UInt32 in
{
COM_TRY_BEGIN
+ // if (op == NUpdateNotifyOp::kOpFinished) return Callback->ReportFinished(indexType, index);
+
bool isDir = false;
if (indexType == NArchive::NEventIndexType::kOutArcIndex)
@@ -676,7 +766,7 @@ 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));
}
@@ -731,7 +821,7 @@ 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)
@@ -752,6 +842,51 @@ STDMETHODIMP CArchiveUpdateCallback::ReportExtractResult(UInt32 indexType, UInt3
COM_TRY_END
}
+
+/*
+STDMETHODIMP CArchiveUpdateCallback::DoNeedArcProp(PROPID propID, Int32 *answer)
+{
+ *answer = 0;
+ if (Need_ArcMTime_Report && propID == kpidComboMTime)
+ *answer = 1;
+ return S_OK;
+}
+
+STDMETHODIMP 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);
+}
+
+STDMETHODIMP CArchiveUpdateCallback::ReportRawProp(UInt32 indexType, UInt32 index,
+ PROPID propID, const void *data, UInt32 dataSize, UInt32 propType)
+{
+ return Callback->ReportRawProp(indexType, index, propID, data, dataSize, propType);
+}
+
+STDMETHODIMP CArchiveUpdateCallback::ReportFinished(UInt32 indexType, UInt32 index, Int32 opRes)
+{
+ return Callback->ReportFinished(indexType, index, opRes);
+}
+*/
+
STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size)
{
if (VolumesSizes.Size() == 0)
@@ -805,7 +940,7 @@ HRESULT CArchiveUpdateCallback::InFileStream_On_Error(UINT_PTR val, DWORD error)
#endif
{
MT_LOCK
- UInt32 index = (UInt32)val;
+ const UInt32 index = (UInt32)val;
FOR_VECTOR(i, _openFiles_Indexes)
{
if (_openFiles_Indexes[i] == index)
@@ -818,21 +953,31 @@ 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;
}
}
- }
/* 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,
diff --git a/CPP/7zip/UI/Common/UpdateCallback.h b/CPP/7zip/UI/Common/UpdateCallback.h
index d27776ef..3719c1ea 100644..100755
--- a/CPP/7zip/UI/Common/UpdateCallback.h
+++ b/CPP/7zip/UI/Common/UpdateCallback.h
@@ -45,6 +45,13 @@ struct CArcToDoStat
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; } */
struct IUpdateCallbackUI
@@ -70,6 +77,7 @@ struct CKeyKeyValPair
class CArchiveUpdateCallback:
public IArchiveUpdateCallback2,
public IArchiveUpdateCallbackFile,
+ // public IArchiveUpdateCallbackArcProp,
public IArchiveExtractCallbackMessage,
public IArchiveGetRawProps,
public IArchiveGetRootProps,
@@ -92,6 +100,7 @@ class CArchiveUpdateCallback:
public:
MY_QUERYINTERFACE_BEGIN2(IArchiveUpdateCallback2)
MY_QUERYINTERFACE_ENTRY(IArchiveUpdateCallbackFile)
+ // MY_QUERYINTERFACE_ENTRY(IArchiveUpdateCallbackArcProp)
MY_QUERYINTERFACE_ENTRY(IArchiveExtractCallbackMessage)
MY_QUERYINTERFACE_ENTRY(IArchiveGetRawProps)
MY_QUERYINTERFACE_ENTRY(IArchiveGetRootProps)
@@ -106,6 +115,7 @@ public:
INTERFACE_IArchiveUpdateCallback2(;)
INTERFACE_IArchiveUpdateCallbackFile(;)
+ // INTERFACE_IArchiveUpdateCallbackArcProp(;)
INTERFACE_IArchiveExtractCallbackMessage(;)
INTERFACE_IArchiveGetRawProps(;)
INTERFACE_IArchiveGetRootProps(;)
@@ -115,10 +125,11 @@ public:
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);
+ virtual void InFileStream_On_Destroy(CInFileStream *stream, UINT_PTR val);
CRecordVector<UInt64> VolumesSizes;
FString VolName;
@@ -148,8 +159,22 @@ public:
bool StoreHardLinks;
bool StoreSymLinks;
+ bool StoreOwnerId;
+ bool StoreOwnerName;
+
+ /*
+ bool Need_ArcMTime_Report;
+ bool ArcMTime_WasReported;
+ CArcTime Reported_ArcMTime;
+ */
+ bool Need_LatestMTime;
+ bool LatestMTime_Defined;
+ CFiTime LatestMTime;
+
Byte *ProcessedItemsStatuses;
+
+
CArchiveUpdateCallback();
bool IsDir(const CUpdatePair2 &up) const
diff --git a/CPP/7zip/UI/Common/UpdatePair.cpp b/CPP/7zip/UI/Common/UpdatePair.cpp
index 31d73f94..e9a16444 100644..100755
--- a/CPP/7zip/UI/Common/UpdatePair.cpp
+++ b/CPP/7zip/UI/Common/UpdatePair.cpp
@@ -3,6 +3,7 @@
#include "StdAfx.h"
#include <time.h>
+// #include <stdio.h>
#include "../../../Common/Wildcard.h"
@@ -14,30 +15,90 @@
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 * 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):";
@@ -64,8 +125,8 @@ 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]);
if (res != 0)
@@ -81,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);
{
@@ -184,7 +245,7 @@ void GetUpdatePairInfoList(
}
else
{
- int dupl = duplicatedArcItem[arcIndex];
+ const int dupl = duplicatedArcItem[arcIndex];
if (dupl != 0)
ThrowError(k_Duplicate_inArc_Message, ai->Name, arcItems[arcIndices[(unsigned)((int)arcIndex + dupl)]].Name);
@@ -195,14 +256,17 @@ void GetUpdatePairInfoList(
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(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;
}
@@ -211,7 +275,10 @@ void GetUpdatePairInfoList(
arcIndex++;
}
- if ((di && di->IsAltStream) ||
+ if (
+ #ifdef _WIN32
+ (di && di->IsAltStream) ||
+ #endif
(ai && ai->IsAltStream))
{
if (prevHostName)
diff --git a/CPP/7zip/UI/Common/UpdatePair.h b/CPP/7zip/UI/Common/UpdatePair.h
index 296d3b09..296d3b09 100644..100755
--- a/CPP/7zip/UI/Common/UpdatePair.h
+++ b/CPP/7zip/UI/Common/UpdatePair.h
diff --git a/CPP/7zip/UI/Common/UpdateProduce.cpp b/CPP/7zip/UI/Common/UpdateProduce.cpp
index fa4bd69c..e921dc32 100644..100755
--- a/CPP/7zip/UI/Common/UpdateProduce.cpp
+++ b/CPP/7zip/UI/Common/UpdateProduce.cpp
@@ -63,6 +63,8 @@ void UpdateProduce(
break;
}
+ up2.IsSameTime = ((unsigned)pair.State == NUpdateArchive::NPairState::kSameFiles);
+
operationChain.Add(up2);
}
diff --git a/CPP/7zip/UI/Common/UpdateProduce.h b/CPP/7zip/UI/Common/UpdateProduce.h
index 595370fe..24bb32ec 100644..100755
--- a/CPP/7zip/UI/Common/UpdateProduce.h
+++ b/CPP/7zip/UI/Common/UpdateProduce.h
@@ -17,6 +17,7 @@ struct CUpdatePair2
int NewNameIndex;
bool IsMainRenameItem;
+ bool IsSameTime;
void SetAs_NoChangeArcItem(unsigned arcIndex) // int
{
@@ -37,7 +38,8 @@ struct CUpdatePair2
DirIndex(-1),
ArcIndex(-1),
NewNameIndex(-1),
- IsMainRenameItem(false)
+ IsMainRenameItem(false),
+ IsSameTime(false)
{}
};
diff --git a/CPP/7zip/UI/Common/WorkDir.cpp b/CPP/7zip/UI/Common/WorkDir.cpp
index 1307ceeb..1307ceeb 100644..100755
--- a/CPP/7zip/UI/Common/WorkDir.cpp
+++ b/CPP/7zip/UI/Common/WorkDir.cpp
diff --git a/CPP/7zip/UI/Common/WorkDir.h b/CPP/7zip/UI/Common/WorkDir.h
index 75850a92..75850a92 100644..100755
--- a/CPP/7zip/UI/Common/WorkDir.h
+++ b/CPP/7zip/UI/Common/WorkDir.h
diff --git a/CPP/7zip/UI/Common/ZipRegistry.cpp b/CPP/7zip/UI/Common/ZipRegistry.cpp
index ab4871fb..a67a99b6 100644..100755
--- a/CPP/7zip/UI/Common/ZipRegistry.cpp
+++ b/CPP/7zip/UI/Common/ZipRegistry.cpp
@@ -33,12 +33,45 @@ static LONG CreateMainKey(CKey &key, LPCTSTR keyName)
return key.Create(HKEY_CURRENT_USER, GetKeyPath(keyName));
}
+static void Key_Set_UInt32(CKey &key, LPCTSTR name, UInt32 value)
+{
+ if (value == (UInt32)(Int32)-1)
+ key.DeleteValue(name);
+ else
+ key.SetValue(name, value);
+}
+
+
+static void Key_Get_UInt32(CKey &key, LPCTSTR name, UInt32 &value)
+{
+ if (key.QueryValue(name, value) != ERROR_SUCCESS)
+ value = (UInt32)(Int32)-1;
+}
+
+
static void Key_Set_BoolPair(CKey &key, LPCTSTR name, const CBoolPair &b)
{
if (b.Def)
key.SetValue(name, b.Val);
}
+static void Key_Set_bool_if_Changed(CKey &key, LPCTSTR name, bool val)
+{
+ bool oldVal = false;
+ if (key.GetValue_IfOk(name, oldVal) == ERROR_SUCCESS)
+ if (val == oldVal)
+ return;
+ key.SetValue(name, val);
+}
+
+static void Key_Set_BoolPair_Delete_IfNotDef(CKey &key, LPCTSTR name, const CBoolPair &b)
+{
+ if (b.Def)
+ Key_Set_bool_if_Changed(key, name, b.Val);
+ else
+ key.DeleteValue(name);
+}
+
static void Key_Get_BoolPair(CKey &key, LPCTSTR name, CBoolPair &b)
{
b.Val = false;
@@ -169,6 +202,13 @@ static LPCTSTR const kNtSecur = TEXT("Security");
static LPCTSTR const kAltStreams = TEXT("AltStreams");
static LPCTSTR const kHardLinks = TEXT("HardLinks");
static LPCTSTR const kSymLinks = TEXT("SymLinks");
+static LPCTSTR const kPreserveATime = TEXT("PreserveATime");
+
+static LPCTSTR const kTimePrec = TEXT("TimePrec");
+static LPCTSTR const kMTime = TEXT("MTime");
+static LPCTSTR const kATime = TEXT("ATime");
+static LPCTSTR const kCTime = TEXT("CTime");
+static LPCTSTR const kSetArcMTime = TEXT("SetArcMTime");
static void SetRegString(CKey &key, LPCWSTR name, const UString &value)
{
@@ -178,26 +218,12 @@ static void SetRegString(CKey &key, LPCWSTR name, const UString &value)
key.SetValue(name, value);
}
-static void SetRegUInt32(CKey &key, LPCTSTR name, UInt32 value)
-{
- if (value == (UInt32)(Int32)-1)
- key.DeleteValue(name);
- else
- key.SetValue(name, value);
-}
-
static void GetRegString(CKey &key, LPCWSTR name, UString &value)
{
if (key.QueryValue(name, value) != ERROR_SUCCESS)
value.Empty();
}
-static void GetRegUInt32(CKey &key, LPCTSTR name, UInt32 &value)
-{
- if (key.QueryValue(name, value) != ERROR_SUCCESS)
- value = (UInt32)(Int32)-1;
-}
-
static LPCWSTR const kMemUse = L"MemUse"
#if defined(MY_CPU_SIZEOF_POINTER) && (MY_CPU_SIZEOF_POINTER == 4)
L"32";
@@ -212,10 +238,11 @@ void CInfo::Save() const
CKey key;
CreateMainKey(key, kKeyName);
- Key_Set_BoolPair(key, kNtSecur, NtSecurity);
- Key_Set_BoolPair(key, kAltStreams, AltStreams);
- Key_Set_BoolPair(key, kHardLinks, HardLinks);
- Key_Set_BoolPair(key, kSymLinks, SymLinks);
+ Key_Set_BoolPair_Delete_IfNotDef (key, kNtSecur, NtSecurity);
+ Key_Set_BoolPair_Delete_IfNotDef (key, kAltStreams, AltStreams);
+ Key_Set_BoolPair_Delete_IfNotDef (key, kHardLinks, HardLinks);
+ Key_Set_BoolPair_Delete_IfNotDef (key, kSymLinks, SymLinks);
+ Key_Set_BoolPair_Delete_IfNotDef (key, kPreserveATime, PreserveATime);
key.SetValue(kShowPassword, ShowPassword);
key.SetValue(kLevel, (UInt32)Level);
@@ -235,16 +262,22 @@ void CInfo::Save() const
CKey fk;
fk.Create(optionsKey, fo.FormatID);
- SetRegUInt32(fk, kLevel, fo.Level);
- SetRegUInt32(fk, kDictionary, fo.Dictionary);
- SetRegUInt32(fk, kOrder, fo.Order);
- SetRegUInt32(fk, kBlockSize, fo.BlockLogSize);
- SetRegUInt32(fk, kNumThreads, fo.NumThreads);
-
SetRegString(fk, kMethod, fo.Method);
SetRegString(fk, kOptions, fo.Options);
SetRegString(fk, kEncryptionMethod, fo.EncryptionMethod);
SetRegString(fk, kMemUse, fo.MemUse);
+
+ Key_Set_UInt32(fk, kLevel, fo.Level);
+ Key_Set_UInt32(fk, kDictionary, fo.Dictionary);
+ Key_Set_UInt32(fk, kOrder, fo.Order);
+ Key_Set_UInt32(fk, kBlockSize, fo.BlockLogSize);
+ Key_Set_UInt32(fk, kNumThreads, fo.NumThreads);
+
+ Key_Set_UInt32(fk, kTimePrec, fo.TimePrec);
+ Key_Set_BoolPair_Delete_IfNotDef (fk, kMTime, fo.MTime);
+ Key_Set_BoolPair_Delete_IfNotDef (fk, kATime, fo.ATime);
+ Key_Set_BoolPair_Delete_IfNotDef (fk, kCTime, fo.CTime);
+ Key_Set_BoolPair_Delete_IfNotDef (fk, kSetArcMTime, fo.SetArcMTime);
}
}
}
@@ -269,6 +302,7 @@ void CInfo::Load()
Key_Get_BoolPair(key, kAltStreams, AltStreams);
Key_Get_BoolPair(key, kHardLinks, HardLinks);
Key_Get_BoolPair(key, kSymLinks, SymLinks);
+ Key_Get_BoolPair(key, kPreserveATime, PreserveATime);
key.GetValue_Strings(kArcHistory, ArcPaths);
@@ -290,11 +324,17 @@ void CInfo::Load()
GetRegString(fk, kEncryptionMethod, fo.EncryptionMethod);
GetRegString(fk, kMemUse, fo.MemUse);
- GetRegUInt32(fk, kLevel, fo.Level);
- GetRegUInt32(fk, kDictionary, fo.Dictionary);
- GetRegUInt32(fk, kOrder, fo.Order);
- GetRegUInt32(fk, kBlockSize, fo.BlockLogSize);
- GetRegUInt32(fk, kNumThreads, fo.NumThreads);
+ Key_Get_UInt32(fk, kLevel, fo.Level);
+ Key_Get_UInt32(fk, kDictionary, fo.Dictionary);
+ Key_Get_UInt32(fk, kOrder, fo.Order);
+ Key_Get_UInt32(fk, kBlockSize, fo.BlockLogSize);
+ Key_Get_UInt32(fk, kNumThreads, fo.NumThreads);
+
+ Key_Get_UInt32(fk, kTimePrec, fo.TimePrec);
+ Key_Get_BoolPair(fk, kMTime, fo.MTime);
+ Key_Get_BoolPair(fk, kATime, fo.ATime);
+ Key_Get_BoolPair(fk, kCTime, fo.CTime);
+ Key_Get_BoolPair(fk, kSetArcMTime, fo.SetArcMTime);
Formats.Add(fo);
}
@@ -478,6 +518,7 @@ static LPCTSTR const kCascadedMenu = TEXT("CascadedMenu");
static LPCTSTR const kContextMenu = TEXT("ContextMenu");
static LPCTSTR const kMenuIcons = TEXT("MenuIcons");
static LPCTSTR const kElimDup = TEXT("ElimDupExtract");
+static LPCTSTR const kWriteZoneId = TEXT("WriteZoneIdExtract");
void CContextMenuInfo::Save() const
{
@@ -488,6 +529,8 @@ void CContextMenuInfo::Save() const
Key_Set_BoolPair(key, kCascadedMenu, Cascaded);
Key_Set_BoolPair(key, kMenuIcons, MenuIcons);
Key_Set_BoolPair(key, kElimDup, ElimDup);
+
+ Key_Set_UInt32(key, kWriteZoneId, WriteZone);
if (Flags_Def)
key.SetValue(kContextMenu, Flags);
@@ -504,6 +547,8 @@ void CContextMenuInfo::Load()
ElimDup.Val = true;
ElimDup.Def = false;
+ WriteZone = (UInt32)(Int32)-1;
+
Flags = (UInt32)(Int32)-1;
Flags_Def = false;
@@ -517,5 +562,7 @@ void CContextMenuInfo::Load()
Key_Get_BoolPair_true(key, kElimDup, ElimDup);
Key_Get_BoolPair(key, kMenuIcons, MenuIcons);
+ Key_Get_UInt32(key, kWriteZoneId, WriteZone);
+
Flags_Def = (key.GetValue_IfOk(kContextMenu, Flags) == ERROR_SUCCESS);
}
diff --git a/CPP/7zip/UI/Common/ZipRegistry.h b/CPP/7zip/UI/Common/ZipRegistry.h
index 3d2e4b98..b7075e67 100644..100755
--- a/CPP/7zip/UI/Common/ZipRegistry.h
+++ b/CPP/7zip/UI/Common/ZipRegistry.h
@@ -10,6 +10,16 @@
#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
@@ -75,12 +85,29 @@ namespace NCompression
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;
@@ -93,7 +120,12 @@ namespace NCompression
// Options.Empty();
// EncryptionMethod.Empty();
}
- CFormatOptions() { ResetForLevelChange(); }
+ CFormatOptions()
+ {
+ // TimePrec = 0;
+ Reset_TimePrec();
+ ResetForLevelChange();
+ }
};
struct CInfo
@@ -111,6 +143,8 @@ namespace NCompression
CBoolPair HardLinks;
CBoolPair SymLinks;
+ CBoolPair PreserveATime;
+
void Save() const;
void Load();
};
@@ -152,9 +186,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/CPP/7zip/UI/Console/BenchCon.cpp b/CPP/7zip/UI/Console/BenchCon.cpp
index a7c9e676..a7c9e676 100644..100755
--- a/CPP/7zip/UI/Console/BenchCon.cpp
+++ b/CPP/7zip/UI/Console/BenchCon.cpp
diff --git a/CPP/7zip/UI/Console/BenchCon.h b/CPP/7zip/UI/Console/BenchCon.h
index c9da1de3..c9da1de3 100644..100755
--- a/CPP/7zip/UI/Console/BenchCon.h
+++ b/CPP/7zip/UI/Console/BenchCon.h
diff --git a/CPP/7zip/UI/Console/Console.dsp b/CPP/7zip/UI/Console/Console.dsp
index f6a32547..f6a32547 100644..100755
--- a/CPP/7zip/UI/Console/Console.dsp
+++ b/CPP/7zip/UI/Console/Console.dsp
diff --git a/CPP/7zip/UI/Console/Console.dsw b/CPP/7zip/UI/Console/Console.dsw
index 0d93da2f..0d93da2f 100644..100755
--- a/CPP/7zip/UI/Console/Console.dsw
+++ b/CPP/7zip/UI/Console/Console.dsw
diff --git a/CPP/7zip/UI/Console/Console.mak b/CPP/7zip/UI/Console/Console.mak
index bd4c1da4..bd4c1da4 100644..100755
--- a/CPP/7zip/UI/Console/Console.mak
+++ b/CPP/7zip/UI/Console/Console.mak
diff --git a/CPP/7zip/UI/Console/Console.manifest b/CPP/7zip/UI/Console/Console.manifest
index 58b68ced..58b68ced 100644..100755
--- a/CPP/7zip/UI/Console/Console.manifest
+++ b/CPP/7zip/UI/Console/Console.manifest
diff --git a/CPP/7zip/UI/Console/ConsoleClose.cpp b/CPP/7zip/UI/Console/ConsoleClose.cpp
index 9e4c040d..9e4c040d 100644..100755
--- a/CPP/7zip/UI/Console/ConsoleClose.cpp
+++ b/CPP/7zip/UI/Console/ConsoleClose.cpp
diff --git a/CPP/7zip/UI/Console/ConsoleClose.h b/CPP/7zip/UI/Console/ConsoleClose.h
index 9c9e035c..9c9e035c 100644..100755
--- a/CPP/7zip/UI/Console/ConsoleClose.h
+++ b/CPP/7zip/UI/Console/ConsoleClose.h
diff --git a/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp b/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp
index 24c21e8d..7f791b00 100644..100755
--- a/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp
+++ b/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp
@@ -56,6 +56,9 @@ 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)
@@ -66,6 +69,10 @@ HRESULT CExtractScanConsole::ScanError(const FString &path, DWORD systemError)
_se->Flush();
}
return HRESULT_FROM_WIN32(systemError);
+
+ // 22.00: commented
+ // CommonError(path, systemError, true);
+ // return S_OK;
}
diff --git a/CPP/7zip/UI/Console/ExtractCallbackConsole.h b/CPP/7zip/UI/Console/ExtractCallbackConsole.h
index 5ac1d0b0..7964813d 100644..100755
--- a/CPP/7zip/UI/Console/ExtractCallbackConsole.h
+++ b/CPP/7zip/UI/Console/ExtractCallbackConsole.h
@@ -15,12 +15,33 @@
#include "OpenCallbackConsole.h"
+/*
+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: public IDirItemsCallback
{
CStdOutStream *_so;
CStdOutStream *_se;
CPercentPrinter _percent;
+ // CErrorPathCodes2 ScanErrors;
+
bool NeedPercents() const { return _percent._so != NULL; }
void ClosePercentsAndFlush()
diff --git a/CPP/7zip/UI/Console/HashCon.cpp b/CPP/7zip/UI/Console/HashCon.cpp
index 5a349765..5a349765 100644..100755
--- a/CPP/7zip/UI/Console/HashCon.cpp
+++ b/CPP/7zip/UI/Console/HashCon.cpp
diff --git a/CPP/7zip/UI/Console/HashCon.h b/CPP/7zip/UI/Console/HashCon.h
index f926d4d3..f926d4d3 100644..100755
--- a/CPP/7zip/UI/Console/HashCon.h
+++ b/CPP/7zip/UI/Console/HashCon.h
diff --git a/CPP/7zip/UI/Console/List.cpp b/CPP/7zip/UI/Console/List.cpp
index 9000e57a..f764f07e 100644..100755
--- a/CPP/7zip/UI/Console/List.cpp
+++ b/CPP/7zip/UI/Console/List.cpp
@@ -124,6 +124,13 @@ static const char * const kPropIdToName[] =
, "Read-only"
, "Out Name"
, "Copy Link"
+ , "ArcFileName"
+ , "IsHash"
+ , "Metadata Changed"
+ , "User ID"
+ , "Group ID"
+ , "Device Major"
+ , "Device Minor"
};
static const char kEmptyAttribChar = '.';
@@ -303,22 +310,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;
@@ -493,12 +496,24 @@ 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;
- ConvertUtcFileTimeToString(*ft, dest, kTimestampPrintLevel_SEC);
+ 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
@@ -631,7 +646,13 @@ 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));
}
@@ -653,7 +674,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
@@ -726,7 +749,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)
@@ -770,16 +793,14 @@ static HRESULT GetUInt64Value(IInArchive *archive, UInt32 index, PROPID propID,
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));
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;
@@ -879,7 +900,8 @@ static void PrintPropPair(CStdOutStream &so, const char *name, const wchar_t *va
static void PrintPropertyPair2(CStdOutStream &so, PROPID propID, const wchar_t *name, const CPropVariant &prop)
{
UString s;
- ConvertPropertyToString2(s, prop, propID);
+ const int levelTopLimit = 9; // 1ns level
+ ConvertPropertyToString2(s, prop, propID, levelTopLimit);
if (!s.IsEmpty())
{
AString nameA;
@@ -1249,7 +1271,7 @@ HRESULT ListArchives(
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;
diff --git a/CPP/7zip/UI/Console/List.h b/CPP/7zip/UI/Console/List.h
index 79d2ed48..79d2ed48 100644..100755
--- a/CPP/7zip/UI/Console/List.h
+++ b/CPP/7zip/UI/Console/List.h
diff --git a/CPP/7zip/UI/Console/Main.cpp b/CPP/7zip/UI/Console/Main.cpp
index 0455ed5d..d01aa4d0 100644..100755
--- a/CPP/7zip/UI/Console/Main.cpp
+++ b/CPP/7zip/UI/Console/Main.cpp
@@ -75,6 +75,8 @@ extern const CHasherInfo *g_Hashers[];
const CExternalCodecs *g_ExternalCodecs_Ptr;
#endif
+DECLARE_AND_SET_CLIENT_VERSION_VAR
+
#if defined(PROG_VARIANT_Z)
#define PROG_POSTFIX "z"
#define PROG_POSTFIX_2 " (z)"
@@ -510,7 +512,7 @@ static void PrintStat()
, &creationTimeFT, &exitTimeFT, &kernelTimeFT, &userTimeFT))
return;
FILETIME curTimeFT;
- NTime::GetCurUtcFileTime(curTimeFT);
+ NTime::GetCurUtc_FiTime(curTimeFT);
#ifndef UNDER_CE
@@ -845,7 +847,7 @@ int Main2(
#if !defined(UNDER_CE)
CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &consoleInfo))
- consoleWidth = (unsigned)consoleInfo.dwSize.X;
+ consoleWidth = (unsigned)(unsigned short)consoleInfo.dwSize.X;
#endif
#else
@@ -859,7 +861,7 @@ 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);
@@ -952,9 +954,11 @@ int Main2(
so << endl << "Formats:" << endl;
- const char * const kArcFlags = "KSNFMGOPBELHXC";
+ 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];
@@ -967,12 +971,22 @@ int Main2(
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 << ' ';
diff --git a/CPP/7zip/UI/Console/MainAr.cpp b/CPP/7zip/UI/Console/MainAr.cpp
index 0e45312c..0e45312c 100644..100755
--- a/CPP/7zip/UI/Console/MainAr.cpp
+++ b/CPP/7zip/UI/Console/MainAr.cpp
diff --git a/CPP/7zip/UI/Console/OpenCallbackConsole.cpp b/CPP/7zip/UI/Console/OpenCallbackConsole.cpp
index a074fa1f..a074fa1f 100644..100755
--- a/CPP/7zip/UI/Console/OpenCallbackConsole.cpp
+++ b/CPP/7zip/UI/Console/OpenCallbackConsole.cpp
diff --git a/CPP/7zip/UI/Console/OpenCallbackConsole.h b/CPP/7zip/UI/Console/OpenCallbackConsole.h
index 075d3741..075d3741 100644..100755
--- a/CPP/7zip/UI/Console/OpenCallbackConsole.h
+++ b/CPP/7zip/UI/Console/OpenCallbackConsole.h
diff --git a/CPP/7zip/UI/Console/PercentPrinter.cpp b/CPP/7zip/UI/Console/PercentPrinter.cpp
index 4341fd9f..49d03932 100644..100755
--- a/CPP/7zip/UI/Console/PercentPrinter.cpp
+++ b/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';
diff --git a/CPP/7zip/UI/Console/PercentPrinter.h b/CPP/7zip/UI/Console/PercentPrinter.h
index 95290b37..95290b37 100644..100755
--- a/CPP/7zip/UI/Console/PercentPrinter.h
+++ b/CPP/7zip/UI/Console/PercentPrinter.h
diff --git a/CPP/7zip/UI/Console/StdAfx.cpp b/CPP/7zip/UI/Console/StdAfx.cpp
index d0feea85..d0feea85 100644..100755
--- a/CPP/7zip/UI/Console/StdAfx.cpp
+++ b/CPP/7zip/UI/Console/StdAfx.cpp
diff --git a/CPP/7zip/UI/Console/StdAfx.h b/CPP/7zip/UI/Console/StdAfx.h
index 2854ff3e..2854ff3e 100644..100755
--- a/CPP/7zip/UI/Console/StdAfx.h
+++ b/CPP/7zip/UI/Console/StdAfx.h
diff --git a/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp b/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp
index 0a25c225..1a6b820c 100644..100755
--- a/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp
+++ b/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp
@@ -11,6 +11,8 @@
#include "../../../Windows/Synchronization.h"
#endif
+// #include "../Common/PropIDUtils.h"
+
#include "ConsoleClose.h"
#include "UserInputUtils.h"
#include "UpdateCallbackConsole.h"
@@ -195,6 +197,22 @@ void CCallbackConsoleBase::CommonError(const FString &path, DWORD systemError, b
}
}
+/*
+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)
{
@@ -519,6 +537,28 @@ HRESULT CCallbackConsoleBase::PrintProgress(const wchar_t *name, bool isDir, con
return CheckBreak2();
}
+
+/*
+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)
@@ -562,10 +602,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;
}
@@ -616,6 +665,8 @@ HRESULT CUpdateCallbackConsole::ReportUpdateOperation(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';
@@ -710,3 +761,119 @@ HRESULT CUpdateCallbackConsole::ShowDeleteFile(const wchar_t *name, bool isDir)
}
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/CPP/7zip/UI/Console/UpdateCallbackConsole.h b/CPP/7zip/UI/Console/UpdateCallbackConsole.h
index 700d511c..b7ffef03 100644..100755
--- a/CPP/7zip/UI/Console/UpdateCallbackConsole.h
+++ b/CPP/7zip/UI/Console/UpdateCallbackConsole.h
@@ -35,7 +35,8 @@ 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);
@@ -89,6 +90,8 @@ public:
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
diff --git a/CPP/7zip/UI/Console/UserInputUtils.cpp b/CPP/7zip/UI/Console/UserInputUtils.cpp
index 93f60eb2..93f60eb2 100644..100755
--- a/CPP/7zip/UI/Console/UserInputUtils.cpp
+++ b/CPP/7zip/UI/Console/UserInputUtils.cpp
diff --git a/CPP/7zip/UI/Console/UserInputUtils.h b/CPP/7zip/UI/Console/UserInputUtils.h
index 256feafe..256feafe 100644..100755
--- a/CPP/7zip/UI/Console/UserInputUtils.h
+++ b/CPP/7zip/UI/Console/UserInputUtils.h
diff --git a/CPP/7zip/UI/Console/makefile b/CPP/7zip/UI/Console/makefile
index acc3f107..acc3f107 100644..100755
--- a/CPP/7zip/UI/Console/makefile
+++ b/CPP/7zip/UI/Console/makefile
diff --git a/CPP/7zip/UI/Console/makefile.gcc b/CPP/7zip/UI/Console/makefile.gcc
index ed05a142..ed05a142 100644..100755
--- a/CPP/7zip/UI/Console/makefile.gcc
+++ b/CPP/7zip/UI/Console/makefile.gcc
diff --git a/CPP/7zip/UI/Console/resource.rc b/CPP/7zip/UI/Console/resource.rc
index 414427fb..414427fb 100644..100755
--- a/CPP/7zip/UI/Console/resource.rc
+++ b/CPP/7zip/UI/Console/resource.rc
diff --git a/CPP/7zip/UI/Explorer/7-zip.dll.manifest b/CPP/7zip/UI/Explorer/7-zip.dll.manifest
index cba1c5df..cba1c5df 100644..100755
--- a/CPP/7zip/UI/Explorer/7-zip.dll.manifest
+++ b/CPP/7zip/UI/Explorer/7-zip.dll.manifest
diff --git a/CPP/7zip/UI/Explorer/ContextMenu.cpp b/CPP/7zip/UI/Explorer/ContextMenu.cpp
index 69070211..7dbb5049 100644..100755
--- a/CPP/7zip/UI/Explorer/ContextMenu.cpp
+++ b/CPP/7zip/UI/Explorer/ContextMenu.cpp
@@ -102,6 +102,7 @@ CZipContextMenu::CZipContextMenu():
_isMenuForFM(false),
_dropMode(false),
_bitmap(NULL),
+ _writeZone((UInt32)(Int32)-1),
IsSeparator(false),
IsRoot(true),
CurrentSubCommand(0)
@@ -560,6 +561,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
ci.Load();
_elimDup = ci.ElimDup;
+ _writeZone = ci.WriteZone;
HBITMAP bitmap = NULL;
if (ci.MenuIcons.Val)
@@ -1167,7 +1169,8 @@ HRESULT CZipContextMenu::InvokeCommandCommon(const CCommandMapItem &cmi)
{
ExtractArchives(_fileNames, cmi.Folder,
(cmdID == kExtract), // showDialog
- (cmdID == kExtractTo) && _elimDup.Val // elimDup
+ (cmdID == kExtractTo) && _elimDup.Val, // elimDup
+ _writeZone
);
break;
}
diff --git a/CPP/7zip/UI/Explorer/ContextMenu.h b/CPP/7zip/UI/Explorer/ContextMenu.h
index 285044e7..5b56d63b 100644..100755
--- a/CPP/7zip/UI/Explorer/ContextMenu.h
+++ b/CPP/7zip/UI/Explorer/ContextMenu.h
@@ -129,6 +129,7 @@ private:
HBITMAP _bitmap;
CBoolPair _elimDup;
+ UInt32 _writeZone;
bool IsSeparator;
bool IsRoot;
diff --git a/CPP/7zip/UI/Explorer/ContextMenuFlags.h b/CPP/7zip/UI/Explorer/ContextMenuFlags.h
index 42b25f3a..42b25f3a 100644..100755
--- a/CPP/7zip/UI/Explorer/ContextMenuFlags.h
+++ b/CPP/7zip/UI/Explorer/ContextMenuFlags.h
diff --git a/CPP/7zip/UI/Explorer/DllExportsExplorer.cpp b/CPP/7zip/UI/Explorer/DllExportsExplorer.cpp
index 91b0da52..91b0da52 100644..100755
--- a/CPP/7zip/UI/Explorer/DllExportsExplorer.cpp
+++ b/CPP/7zip/UI/Explorer/DllExportsExplorer.cpp
diff --git a/CPP/7zip/UI/Explorer/Explorer.def b/CPP/7zip/UI/Explorer/Explorer.def
index 034a269d..034a269d 100644..100755
--- a/CPP/7zip/UI/Explorer/Explorer.def
+++ b/CPP/7zip/UI/Explorer/Explorer.def
diff --git a/CPP/7zip/UI/Explorer/Explorer.dsp b/CPP/7zip/UI/Explorer/Explorer.dsp
index e3909176..e3909176 100644..100755
--- a/CPP/7zip/UI/Explorer/Explorer.dsp
+++ b/CPP/7zip/UI/Explorer/Explorer.dsp
diff --git a/CPP/7zip/UI/Explorer/Explorer.dsw b/CPP/7zip/UI/Explorer/Explorer.dsw
index beb8df7b..beb8df7b 100644..100755
--- a/CPP/7zip/UI/Explorer/Explorer.dsw
+++ b/CPP/7zip/UI/Explorer/Explorer.dsw
diff --git a/CPP/7zip/UI/Explorer/MenuLogo.bmp b/CPP/7zip/UI/Explorer/MenuLogo.bmp
index 906a6c5c..906a6c5c 100644..100755
--- a/CPP/7zip/UI/Explorer/MenuLogo.bmp
+++ b/CPP/7zip/UI/Explorer/MenuLogo.bmp
Binary files differ
diff --git a/CPP/7zip/UI/Explorer/MyExplorerCommand.h b/CPP/7zip/UI/Explorer/MyExplorerCommand.h
index 227b9e02..227b9e02 100644..100755
--- a/CPP/7zip/UI/Explorer/MyExplorerCommand.h
+++ b/CPP/7zip/UI/Explorer/MyExplorerCommand.h
diff --git a/CPP/7zip/UI/Explorer/MyMessages.cpp b/CPP/7zip/UI/Explorer/MyMessages.cpp
index c912504c..c912504c 100644..100755
--- a/CPP/7zip/UI/Explorer/MyMessages.cpp
+++ b/CPP/7zip/UI/Explorer/MyMessages.cpp
diff --git a/CPP/7zip/UI/Explorer/MyMessages.h b/CPP/7zip/UI/Explorer/MyMessages.h
index d5822f45..d5822f45 100644..100755
--- a/CPP/7zip/UI/Explorer/MyMessages.h
+++ b/CPP/7zip/UI/Explorer/MyMessages.h
diff --git a/CPP/7zip/UI/Explorer/RegistryContextMenu.cpp b/CPP/7zip/UI/Explorer/RegistryContextMenu.cpp
index 9f6e44c8..9f6e44c8 100644..100755
--- a/CPP/7zip/UI/Explorer/RegistryContextMenu.cpp
+++ b/CPP/7zip/UI/Explorer/RegistryContextMenu.cpp
diff --git a/CPP/7zip/UI/Explorer/RegistryContextMenu.h b/CPP/7zip/UI/Explorer/RegistryContextMenu.h
index 8c2acc42..8c2acc42 100644..100755
--- a/CPP/7zip/UI/Explorer/RegistryContextMenu.h
+++ b/CPP/7zip/UI/Explorer/RegistryContextMenu.h
diff --git a/CPP/7zip/UI/Explorer/StdAfx.cpp b/CPP/7zip/UI/Explorer/StdAfx.cpp
index d0feea85..d0feea85 100644..100755
--- a/CPP/7zip/UI/Explorer/StdAfx.cpp
+++ b/CPP/7zip/UI/Explorer/StdAfx.cpp
diff --git a/CPP/7zip/UI/Explorer/StdAfx.h b/CPP/7zip/UI/Explorer/StdAfx.h
index 5e4dc640..5e4dc640 100644..100755
--- a/CPP/7zip/UI/Explorer/StdAfx.h
+++ b/CPP/7zip/UI/Explorer/StdAfx.h
diff --git a/CPP/7zip/UI/Explorer/makefile b/CPP/7zip/UI/Explorer/makefile
index 1e79cc82..1e79cc82 100644..100755
--- a/CPP/7zip/UI/Explorer/makefile
+++ b/CPP/7zip/UI/Explorer/makefile
diff --git a/CPP/7zip/UI/Explorer/resource.h b/CPP/7zip/UI/Explorer/resource.h
index 8bb82108..8bb82108 100644..100755
--- a/CPP/7zip/UI/Explorer/resource.h
+++ b/CPP/7zip/UI/Explorer/resource.h
diff --git a/CPP/7zip/UI/Explorer/resource.rc b/CPP/7zip/UI/Explorer/resource.rc
index 66592908..66592908 100644..100755
--- a/CPP/7zip/UI/Explorer/resource.rc
+++ b/CPP/7zip/UI/Explorer/resource.rc
diff --git a/CPP/7zip/UI/Explorer/resource2.rc b/CPP/7zip/UI/Explorer/resource2.rc
index c07148fd..c07148fd 100644..100755
--- a/CPP/7zip/UI/Explorer/resource2.rc
+++ b/CPP/7zip/UI/Explorer/resource2.rc
diff --git a/CPP/7zip/UI/Far/ExtractEngine.cpp b/CPP/7zip/UI/Far/ExtractEngine.cpp
index ab5c0def..ab5c0def 100644..100755
--- a/CPP/7zip/UI/Far/ExtractEngine.cpp
+++ b/CPP/7zip/UI/Far/ExtractEngine.cpp
diff --git a/CPP/7zip/UI/Far/ExtractEngine.h b/CPP/7zip/UI/Far/ExtractEngine.h
index 5861d92c..5861d92c 100644..100755
--- a/CPP/7zip/UI/Far/ExtractEngine.h
+++ b/CPP/7zip/UI/Far/ExtractEngine.h
diff --git a/CPP/7zip/UI/Far/Far.cpp b/CPP/7zip/UI/Far/Far.cpp
index a9e47916..a9e47916 100644..100755
--- a/CPP/7zip/UI/Far/Far.cpp
+++ b/CPP/7zip/UI/Far/Far.cpp
diff --git a/CPP/7zip/UI/Far/Far.def b/CPP/7zip/UI/Far/Far.def
index 1de9acdf..1de9acdf 100644..100755
--- a/CPP/7zip/UI/Far/Far.def
+++ b/CPP/7zip/UI/Far/Far.def
diff --git a/CPP/7zip/UI/Far/Far.dsp b/CPP/7zip/UI/Far/Far.dsp
index bd6d8fd4..bd6d8fd4 100644..100755
--- a/CPP/7zip/UI/Far/Far.dsp
+++ b/CPP/7zip/UI/Far/Far.dsp
diff --git a/CPP/7zip/UI/Far/Far.dsw b/CPP/7zip/UI/Far/Far.dsw
index f4ef0801..f4ef0801 100644..100755
--- a/CPP/7zip/UI/Far/Far.dsw
+++ b/CPP/7zip/UI/Far/Far.dsw
diff --git a/CPP/7zip/UI/Far/FarPlugin.h b/CPP/7zip/UI/Far/FarPlugin.h
index 859d319f..859d319f 100644..100755
--- a/CPP/7zip/UI/Far/FarPlugin.h
+++ b/CPP/7zip/UI/Far/FarPlugin.h
diff --git a/CPP/7zip/UI/Far/FarUtils.cpp b/CPP/7zip/UI/Far/FarUtils.cpp
index 3bdb9895..3bdb9895 100644..100755
--- a/CPP/7zip/UI/Far/FarUtils.cpp
+++ b/CPP/7zip/UI/Far/FarUtils.cpp
diff --git a/CPP/7zip/UI/Far/FarUtils.h b/CPP/7zip/UI/Far/FarUtils.h
index 38f64f98..38f64f98 100644..100755
--- a/CPP/7zip/UI/Far/FarUtils.h
+++ b/CPP/7zip/UI/Far/FarUtils.h
diff --git a/CPP/7zip/UI/Far/Messages.h b/CPP/7zip/UI/Far/Messages.h
index 4e5ed8d5..4e5ed8d5 100644..100755
--- a/CPP/7zip/UI/Far/Messages.h
+++ b/CPP/7zip/UI/Far/Messages.h
diff --git a/CPP/7zip/UI/Far/OverwriteDialogFar.cpp b/CPP/7zip/UI/Far/OverwriteDialogFar.cpp
index b8fc565f..b8fc565f 100644..100755
--- a/CPP/7zip/UI/Far/OverwriteDialogFar.cpp
+++ b/CPP/7zip/UI/Far/OverwriteDialogFar.cpp
diff --git a/CPP/7zip/UI/Far/OverwriteDialogFar.h b/CPP/7zip/UI/Far/OverwriteDialogFar.h
index 34947436..34947436 100644..100755
--- a/CPP/7zip/UI/Far/OverwriteDialogFar.h
+++ b/CPP/7zip/UI/Far/OverwriteDialogFar.h
diff --git a/CPP/7zip/UI/Far/Plugin.cpp b/CPP/7zip/UI/Far/Plugin.cpp
index 8dc1375a..8dc1375a 100644..100755
--- a/CPP/7zip/UI/Far/Plugin.cpp
+++ b/CPP/7zip/UI/Far/Plugin.cpp
diff --git a/CPP/7zip/UI/Far/Plugin.h b/CPP/7zip/UI/Far/Plugin.h
index 1fe190e4..1fe190e4 100644..100755
--- a/CPP/7zip/UI/Far/Plugin.h
+++ b/CPP/7zip/UI/Far/Plugin.h
diff --git a/CPP/7zip/UI/Far/PluginCommon.cpp b/CPP/7zip/UI/Far/PluginCommon.cpp
index e1d44582..e1d44582 100644..100755
--- a/CPP/7zip/UI/Far/PluginCommon.cpp
+++ b/CPP/7zip/UI/Far/PluginCommon.cpp
diff --git a/CPP/7zip/UI/Far/PluginDelete.cpp b/CPP/7zip/UI/Far/PluginDelete.cpp
index 939a3558..939a3558 100644..100755
--- a/CPP/7zip/UI/Far/PluginDelete.cpp
+++ b/CPP/7zip/UI/Far/PluginDelete.cpp
diff --git a/CPP/7zip/UI/Far/PluginRead.cpp b/CPP/7zip/UI/Far/PluginRead.cpp
index 70e7e141..70e7e141 100644..100755
--- a/CPP/7zip/UI/Far/PluginRead.cpp
+++ b/CPP/7zip/UI/Far/PluginRead.cpp
diff --git a/CPP/7zip/UI/Far/PluginWrite.cpp b/CPP/7zip/UI/Far/PluginWrite.cpp
index 8a76bb4e..8a76bb4e 100644..100755
--- a/CPP/7zip/UI/Far/PluginWrite.cpp
+++ b/CPP/7zip/UI/Far/PluginWrite.cpp
diff --git a/CPP/7zip/UI/Far/ProgressBox.cpp b/CPP/7zip/UI/Far/ProgressBox.cpp
index 6efb132a..6efb132a 100644..100755
--- a/CPP/7zip/UI/Far/ProgressBox.cpp
+++ b/CPP/7zip/UI/Far/ProgressBox.cpp
diff --git a/CPP/7zip/UI/Far/ProgressBox.h b/CPP/7zip/UI/Far/ProgressBox.h
index 54bdb4f1..54bdb4f1 100644..100755
--- a/CPP/7zip/UI/Far/ProgressBox.h
+++ b/CPP/7zip/UI/Far/ProgressBox.h
diff --git a/CPP/7zip/UI/Far/StdAfx.cpp b/CPP/7zip/UI/Far/StdAfx.cpp
index d0feea85..d0feea85 100644..100755
--- a/CPP/7zip/UI/Far/StdAfx.cpp
+++ b/CPP/7zip/UI/Far/StdAfx.cpp
diff --git a/CPP/7zip/UI/Far/StdAfx.h b/CPP/7zip/UI/Far/StdAfx.h
index 2854ff3e..2854ff3e 100644..100755
--- a/CPP/7zip/UI/Far/StdAfx.h
+++ b/CPP/7zip/UI/Far/StdAfx.h
diff --git a/CPP/7zip/UI/Far/UpdateCallbackFar.cpp b/CPP/7zip/UI/Far/UpdateCallbackFar.cpp
index 3f0f206b..3f0f206b 100644..100755
--- a/CPP/7zip/UI/Far/UpdateCallbackFar.cpp
+++ b/CPP/7zip/UI/Far/UpdateCallbackFar.cpp
diff --git a/CPP/7zip/UI/Far/UpdateCallbackFar.h b/CPP/7zip/UI/Far/UpdateCallbackFar.h
index d2c2c8ed..d2c2c8ed 100644..100755
--- a/CPP/7zip/UI/Far/UpdateCallbackFar.h
+++ b/CPP/7zip/UI/Far/UpdateCallbackFar.h
diff --git a/CPP/7zip/UI/Far/makefile b/CPP/7zip/UI/Far/makefile
index 0db22749..0db22749 100644..100755
--- a/CPP/7zip/UI/Far/makefile
+++ b/CPP/7zip/UI/Far/makefile
diff --git a/CPP/7zip/UI/Far/resource.rc b/CPP/7zip/UI/Far/resource.rc
index a5c2e2f3..a5c2e2f3 100644..100755
--- a/CPP/7zip/UI/Far/resource.rc
+++ b/CPP/7zip/UI/Far/resource.rc
diff --git a/CPP/7zip/UI/FileManager/7zFM.exe.manifest b/CPP/7zip/UI/FileManager/7zFM.exe.manifest
index 6a13c923..6a13c923 100644..100755
--- a/CPP/7zip/UI/FileManager/7zFM.exe.manifest
+++ b/CPP/7zip/UI/FileManager/7zFM.exe.manifest
diff --git a/CPP/7zip/UI/FileManager/7zipLogo.ico b/CPP/7zip/UI/FileManager/7zipLogo.ico
index 973241c8..973241c8 100644..100755
--- a/CPP/7zip/UI/FileManager/7zipLogo.ico
+++ b/CPP/7zip/UI/FileManager/7zipLogo.ico
Binary files differ
diff --git a/CPP/7zip/UI/FileManager/AboutDialog.cpp b/CPP/7zip/UI/FileManager/AboutDialog.cpp
index 082902e2..082902e2 100644..100755
--- a/CPP/7zip/UI/FileManager/AboutDialog.cpp
+++ b/CPP/7zip/UI/FileManager/AboutDialog.cpp
diff --git a/CPP/7zip/UI/FileManager/AboutDialog.h b/CPP/7zip/UI/FileManager/AboutDialog.h
index 39fd3ba7..39fd3ba7 100644..100755
--- a/CPP/7zip/UI/FileManager/AboutDialog.h
+++ b/CPP/7zip/UI/FileManager/AboutDialog.h
diff --git a/CPP/7zip/UI/FileManager/AboutDialog.rc b/CPP/7zip/UI/FileManager/AboutDialog.rc
index b235df0b..b235df0b 100644..100755
--- a/CPP/7zip/UI/FileManager/AboutDialog.rc
+++ b/CPP/7zip/UI/FileManager/AboutDialog.rc
diff --git a/CPP/7zip/UI/FileManager/AboutDialogRes.h b/CPP/7zip/UI/FileManager/AboutDialogRes.h
index b4165580..b4165580 100644..100755
--- a/CPP/7zip/UI/FileManager/AboutDialogRes.h
+++ b/CPP/7zip/UI/FileManager/AboutDialogRes.h
diff --git a/CPP/7zip/UI/FileManager/Add.bmp b/CPP/7zip/UI/FileManager/Add.bmp
index a8577fc7..a8577fc7 100644..100755
--- a/CPP/7zip/UI/FileManager/Add.bmp
+++ b/CPP/7zip/UI/FileManager/Add.bmp
Binary files differ
diff --git a/CPP/7zip/UI/FileManager/Add2.bmp b/CPP/7zip/UI/FileManager/Add2.bmp
index 252fc253..252fc253 100644..100755
--- a/CPP/7zip/UI/FileManager/Add2.bmp
+++ b/CPP/7zip/UI/FileManager/Add2.bmp
Binary files differ
diff --git a/CPP/7zip/UI/FileManager/AltStreamsFolder.cpp b/CPP/7zip/UI/FileManager/AltStreamsFolder.cpp
index e1c99d3c..e1c99d3c 100644..100755
--- a/CPP/7zip/UI/FileManager/AltStreamsFolder.cpp
+++ b/CPP/7zip/UI/FileManager/AltStreamsFolder.cpp
diff --git a/CPP/7zip/UI/FileManager/AltStreamsFolder.h b/CPP/7zip/UI/FileManager/AltStreamsFolder.h
index ccd0a58f..ccd0a58f 100644..100755
--- a/CPP/7zip/UI/FileManager/AltStreamsFolder.h
+++ b/CPP/7zip/UI/FileManager/AltStreamsFolder.h
diff --git a/CPP/7zip/UI/FileManager/App.cpp b/CPP/7zip/UI/FileManager/App.cpp
index 512acc53..512acc53 100644..100755
--- a/CPP/7zip/UI/FileManager/App.cpp
+++ b/CPP/7zip/UI/FileManager/App.cpp
diff --git a/CPP/7zip/UI/FileManager/App.h b/CPP/7zip/UI/FileManager/App.h
index 3c3c5ef2..3c3c5ef2 100644..100755
--- a/CPP/7zip/UI/FileManager/App.h
+++ b/CPP/7zip/UI/FileManager/App.h
diff --git a/CPP/7zip/UI/FileManager/AppState.h b/CPP/7zip/UI/FileManager/AppState.h
index cc887150..cc887150 100644..100755
--- a/CPP/7zip/UI/FileManager/AppState.h
+++ b/CPP/7zip/UI/FileManager/AppState.h
diff --git a/CPP/7zip/UI/FileManager/BrowseDialog.cpp b/CPP/7zip/UI/FileManager/BrowseDialog.cpp
index 6d2b6b55..6d2b6b55 100644..100755
--- a/CPP/7zip/UI/FileManager/BrowseDialog.cpp
+++ b/CPP/7zip/UI/FileManager/BrowseDialog.cpp
diff --git a/CPP/7zip/UI/FileManager/BrowseDialog.h b/CPP/7zip/UI/FileManager/BrowseDialog.h
index 957af2e2..957af2e2 100644..100755
--- a/CPP/7zip/UI/FileManager/BrowseDialog.h
+++ b/CPP/7zip/UI/FileManager/BrowseDialog.h
diff --git a/CPP/7zip/UI/FileManager/BrowseDialog.rc b/CPP/7zip/UI/FileManager/BrowseDialog.rc
index 04a6ad61..04a6ad61 100644..100755
--- a/CPP/7zip/UI/FileManager/BrowseDialog.rc
+++ b/CPP/7zip/UI/FileManager/BrowseDialog.rc
diff --git a/CPP/7zip/UI/FileManager/BrowseDialogRes.h b/CPP/7zip/UI/FileManager/BrowseDialogRes.h
index aff84ec9..aff84ec9 100644..100755
--- a/CPP/7zip/UI/FileManager/BrowseDialogRes.h
+++ b/CPP/7zip/UI/FileManager/BrowseDialogRes.h
diff --git a/CPP/7zip/UI/FileManager/ClassDefs.cpp b/CPP/7zip/UI/FileManager/ClassDefs.cpp
index 5c269043..5c269043 100644..100755
--- a/CPP/7zip/UI/FileManager/ClassDefs.cpp
+++ b/CPP/7zip/UI/FileManager/ClassDefs.cpp
diff --git a/CPP/7zip/UI/FileManager/ComboDialog.cpp b/CPP/7zip/UI/FileManager/ComboDialog.cpp
index 729743e8..729743e8 100644..100755
--- a/CPP/7zip/UI/FileManager/ComboDialog.cpp
+++ b/CPP/7zip/UI/FileManager/ComboDialog.cpp
diff --git a/CPP/7zip/UI/FileManager/ComboDialog.h b/CPP/7zip/UI/FileManager/ComboDialog.h
index 29b28b5b..29b28b5b 100644..100755
--- a/CPP/7zip/UI/FileManager/ComboDialog.h
+++ b/CPP/7zip/UI/FileManager/ComboDialog.h
diff --git a/CPP/7zip/UI/FileManager/ComboDialog.rc b/CPP/7zip/UI/FileManager/ComboDialog.rc
index fddb7484..fddb7484 100644..100755
--- a/CPP/7zip/UI/FileManager/ComboDialog.rc
+++ b/CPP/7zip/UI/FileManager/ComboDialog.rc
diff --git a/CPP/7zip/UI/FileManager/ComboDialogRes.h b/CPP/7zip/UI/FileManager/ComboDialogRes.h
index a044797e..a044797e 100644..100755
--- a/CPP/7zip/UI/FileManager/ComboDialogRes.h
+++ b/CPP/7zip/UI/FileManager/ComboDialogRes.h
diff --git a/CPP/7zip/UI/FileManager/Copy.bmp b/CPP/7zip/UI/FileManager/Copy.bmp
index 0f28a324..0f28a324 100644..100755
--- a/CPP/7zip/UI/FileManager/Copy.bmp
+++ b/CPP/7zip/UI/FileManager/Copy.bmp
Binary files differ
diff --git a/CPP/7zip/UI/FileManager/Copy2.bmp b/CPP/7zip/UI/FileManager/Copy2.bmp
index ba88ded0..ba88ded0 100644..100755
--- a/CPP/7zip/UI/FileManager/Copy2.bmp
+++ b/CPP/7zip/UI/FileManager/Copy2.bmp
Binary files differ
diff --git a/CPP/7zip/UI/FileManager/CopyDialog.cpp b/CPP/7zip/UI/FileManager/CopyDialog.cpp
index 4b17110d..4b17110d 100644..100755
--- a/CPP/7zip/UI/FileManager/CopyDialog.cpp
+++ b/CPP/7zip/UI/FileManager/CopyDialog.cpp
diff --git a/CPP/7zip/UI/FileManager/CopyDialog.h b/CPP/7zip/UI/FileManager/CopyDialog.h
index 30fde71f..30fde71f 100644..100755
--- a/CPP/7zip/UI/FileManager/CopyDialog.h
+++ b/CPP/7zip/UI/FileManager/CopyDialog.h
diff --git a/CPP/7zip/UI/FileManager/CopyDialog.rc b/CPP/7zip/UI/FileManager/CopyDialog.rc
index 73d3ea80..73d3ea80 100644..100755
--- a/CPP/7zip/UI/FileManager/CopyDialog.rc
+++ b/CPP/7zip/UI/FileManager/CopyDialog.rc
diff --git a/CPP/7zip/UI/FileManager/CopyDialogRes.h b/CPP/7zip/UI/FileManager/CopyDialogRes.h
index 85f5a39a..85f5a39a 100644..100755
--- a/CPP/7zip/UI/FileManager/CopyDialogRes.h
+++ b/CPP/7zip/UI/FileManager/CopyDialogRes.h
diff --git a/CPP/7zip/UI/FileManager/Delete.bmp b/CPP/7zip/UI/FileManager/Delete.bmp
index d1004d82..d1004d82 100644..100755
--- a/CPP/7zip/UI/FileManager/Delete.bmp
+++ b/CPP/7zip/UI/FileManager/Delete.bmp
Binary files differ
diff --git a/CPP/7zip/UI/FileManager/Delete2.bmp b/CPP/7zip/UI/FileManager/Delete2.bmp
index 60e08c6a..60e08c6a 100644..100755
--- a/CPP/7zip/UI/FileManager/Delete2.bmp
+++ b/CPP/7zip/UI/FileManager/Delete2.bmp
Binary files differ
diff --git a/CPP/7zip/UI/FileManager/DialogSize.h b/CPP/7zip/UI/FileManager/DialogSize.h
index 504541bd..504541bd 100644..100755
--- a/CPP/7zip/UI/FileManager/DialogSize.h
+++ b/CPP/7zip/UI/FileManager/DialogSize.h
diff --git a/CPP/7zip/UI/FileManager/EditDialog.cpp b/CPP/7zip/UI/FileManager/EditDialog.cpp
index 7f596722..7f596722 100644..100755
--- a/CPP/7zip/UI/FileManager/EditDialog.cpp
+++ b/CPP/7zip/UI/FileManager/EditDialog.cpp
diff --git a/CPP/7zip/UI/FileManager/EditDialog.h b/CPP/7zip/UI/FileManager/EditDialog.h
index d820516a..d820516a 100644..100755
--- a/CPP/7zip/UI/FileManager/EditDialog.h
+++ b/CPP/7zip/UI/FileManager/EditDialog.h
diff --git a/CPP/7zip/UI/FileManager/EditDialog.rc b/CPP/7zip/UI/FileManager/EditDialog.rc
index cdb0b445..cdb0b445 100644..100755
--- a/CPP/7zip/UI/FileManager/EditDialog.rc
+++ b/CPP/7zip/UI/FileManager/EditDialog.rc
diff --git a/CPP/7zip/UI/FileManager/EditDialogRes.h b/CPP/7zip/UI/FileManager/EditDialogRes.h
index 58c5ca91..58c5ca91 100644..100755
--- a/CPP/7zip/UI/FileManager/EditDialogRes.h
+++ b/CPP/7zip/UI/FileManager/EditDialogRes.h
diff --git a/CPP/7zip/UI/FileManager/EditPage.cpp b/CPP/7zip/UI/FileManager/EditPage.cpp
index 0108904d..0108904d 100644..100755
--- a/CPP/7zip/UI/FileManager/EditPage.cpp
+++ b/CPP/7zip/UI/FileManager/EditPage.cpp
diff --git a/CPP/7zip/UI/FileManager/EditPage.h b/CPP/7zip/UI/FileManager/EditPage.h
index 208edd8d..208edd8d 100644..100755
--- a/CPP/7zip/UI/FileManager/EditPage.h
+++ b/CPP/7zip/UI/FileManager/EditPage.h
diff --git a/CPP/7zip/UI/FileManager/EditPage.rc b/CPP/7zip/UI/FileManager/EditPage.rc
index 38f74ea1..38f74ea1 100644..100755
--- a/CPP/7zip/UI/FileManager/EditPage.rc
+++ b/CPP/7zip/UI/FileManager/EditPage.rc
diff --git a/CPP/7zip/UI/FileManager/EditPage2.rc b/CPP/7zip/UI/FileManager/EditPage2.rc
index 2d6554fb..2d6554fb 100644..100755
--- a/CPP/7zip/UI/FileManager/EditPage2.rc
+++ b/CPP/7zip/UI/FileManager/EditPage2.rc
diff --git a/CPP/7zip/UI/FileManager/EditPageRes.h b/CPP/7zip/UI/FileManager/EditPageRes.h
index 017d7024..017d7024 100644..100755
--- a/CPP/7zip/UI/FileManager/EditPageRes.h
+++ b/CPP/7zip/UI/FileManager/EditPageRes.h
diff --git a/CPP/7zip/UI/FileManager/EnumFormatEtc.cpp b/CPP/7zip/UI/FileManager/EnumFormatEtc.cpp
index 389aa3e8..389aa3e8 100644..100755
--- a/CPP/7zip/UI/FileManager/EnumFormatEtc.cpp
+++ b/CPP/7zip/UI/FileManager/EnumFormatEtc.cpp
diff --git a/CPP/7zip/UI/FileManager/EnumFormatEtc.h b/CPP/7zip/UI/FileManager/EnumFormatEtc.h
index 93a53cb3..93a53cb3 100644..100755
--- a/CPP/7zip/UI/FileManager/EnumFormatEtc.h
+++ b/CPP/7zip/UI/FileManager/EnumFormatEtc.h
diff --git a/CPP/7zip/UI/FileManager/Extract.bmp b/CPP/7zip/UI/FileManager/Extract.bmp
index 0aeba923..0aeba923 100644..100755
--- a/CPP/7zip/UI/FileManager/Extract.bmp
+++ b/CPP/7zip/UI/FileManager/Extract.bmp
Binary files differ
diff --git a/CPP/7zip/UI/FileManager/Extract2.bmp b/CPP/7zip/UI/FileManager/Extract2.bmp
index a7e57753..a7e57753 100644..100755
--- a/CPP/7zip/UI/FileManager/Extract2.bmp
+++ b/CPP/7zip/UI/FileManager/Extract2.bmp
Binary files differ
diff --git a/CPP/7zip/UI/FileManager/ExtractCallback.cpp b/CPP/7zip/UI/FileManager/ExtractCallback.cpp
index 232717f8..232717f8 100644..100755
--- a/CPP/7zip/UI/FileManager/ExtractCallback.cpp
+++ b/CPP/7zip/UI/FileManager/ExtractCallback.cpp
diff --git a/CPP/7zip/UI/FileManager/ExtractCallback.h b/CPP/7zip/UI/FileManager/ExtractCallback.h
index 02578bb4..02578bb4 100644..100755
--- a/CPP/7zip/UI/FileManager/ExtractCallback.h
+++ b/CPP/7zip/UI/FileManager/ExtractCallback.h
diff --git a/CPP/7zip/UI/FileManager/FM.cpp b/CPP/7zip/UI/FileManager/FM.cpp
index 812eff67..812eff67 100644..100755
--- a/CPP/7zip/UI/FileManager/FM.cpp
+++ b/CPP/7zip/UI/FileManager/FM.cpp
diff --git a/CPP/7zip/UI/FileManager/FM.dsp b/CPP/7zip/UI/FileManager/FM.dsp
index a12d3307..a12d3307 100644..100755
--- a/CPP/7zip/UI/FileManager/FM.dsp
+++ b/CPP/7zip/UI/FileManager/FM.dsp
diff --git a/CPP/7zip/UI/FileManager/FM.dsw b/CPP/7zip/UI/FileManager/FM.dsw
index 1c955d95..1c955d95 100644..100755
--- a/CPP/7zip/UI/FileManager/FM.dsw
+++ b/CPP/7zip/UI/FileManager/FM.dsw
diff --git a/CPP/7zip/UI/FileManager/FM.ico b/CPP/7zip/UI/FileManager/FM.ico
index 3a0a34da..3a0a34da 100644..100755
--- a/CPP/7zip/UI/FileManager/FM.ico
+++ b/CPP/7zip/UI/FileManager/FM.ico
Binary files differ
diff --git a/CPP/7zip/UI/FileManager/FM.mak b/CPP/7zip/UI/FileManager/FM.mak
index 8b3d97af..8b3d97af 100644..100755
--- a/CPP/7zip/UI/FileManager/FM.mak
+++ b/CPP/7zip/UI/FileManager/FM.mak
diff --git a/CPP/7zip/UI/FileManager/FSDrives.cpp b/CPP/7zip/UI/FileManager/FSDrives.cpp
index c563907f..c563907f 100644..100755
--- a/CPP/7zip/UI/FileManager/FSDrives.cpp
+++ b/CPP/7zip/UI/FileManager/FSDrives.cpp
diff --git a/CPP/7zip/UI/FileManager/FSDrives.h b/CPP/7zip/UI/FileManager/FSDrives.h
index f12e4da8..f12e4da8 100644..100755
--- a/CPP/7zip/UI/FileManager/FSDrives.h
+++ b/CPP/7zip/UI/FileManager/FSDrives.h
diff --git a/CPP/7zip/UI/FileManager/FSFolder.cpp b/CPP/7zip/UI/FileManager/FSFolder.cpp
index f3e04b3c..72cb0ce0 100644..100755
--- a/CPP/7zip/UI/FileManager/FSFolder.cpp
+++ b/CPP/7zip/UI/FileManager/FSFolder.cpp
@@ -2,11 +2,19 @@
#include "StdAfx.h"
+#if defined(_MSC_VER)
+#include <winternl.h>
+#else
+// mingw
+#include <ddk/winddk.h>
+#endif
+
#include "../../../Common/ComTry.h"
#include "../../../Common/Defs.h"
#include "../../../Common/StringConvert.h"
#include "../../../Common/UTFConvert.h"
+#include "../../../Windows/DLL.h"
#include "../../../Windows/FileDir.h"
#include "../../../Windows/FileIO.h"
#include "../../../Windows/FileName.h"
@@ -56,12 +64,15 @@ static const Byte kProps[] =
kpidMTime,
kpidCTime,
kpidATime,
+ #ifdef FS_SHOW_LINKS_INFO
+ kpidChangeTime,
+ #endif
kpidAttrib,
kpidPackSize,
- #ifdef FS_SHOW_LINKS_INFO
+ #ifdef FS_SHOW_LINKS_INFO
kpidINode,
kpidLinks,
- #endif
+ #endif
kpidComment,
kpidNumSubDirs,
kpidNumSubFiles,
@@ -199,19 +210,23 @@ HRESULT CFSFolder::LoadSubItems(int dirItem, const FString &relPrefix)
*/
}
- #ifndef UNDER_CE
+ #ifndef UNDER_CE
fi.Reparse.Free();
fi.PackSize_Defined = false;
- #ifdef FS_SHOW_LINKS_INFO
+ #ifdef FS_SHOW_LINKS_INFO
fi.FileInfo_Defined = false;
fi.FileInfo_WasRequested = false;
fi.FileIndex = 0;
fi.NumLinks = 0;
- #endif
+ fi.ChangeTime_Defined = false;
+ fi.ChangeTime_WasRequested = false;
+ #endif
fi.PackSize = fi.Size;
+
+ #ifdef FS_SHOW_LINKS_INFO
if (fi.HasReparsePoint())
{
fi.FileInfo_WasRequested = true;
@@ -221,8 +236,9 @@ HRESULT CFSFolder::LoadSubItems(int dirItem, const FString &relPrefix)
fi.FileIndex = (((UInt64)info.nFileIndexHigh) << 32) + info.nFileIndexLow;
fi.FileInfo_Defined = true;
}
+ #endif
- #endif
+ #endif // UNDER_CE
/* unsigned fileIndex = */ Files.Add(fi);
@@ -396,7 +412,9 @@ STDMETHODIMP_(UInt64) CFSFolder::GetItemSize(UInt32 index)
#endif
+
#ifdef FS_SHOW_LINKS_INFO
+
bool CFSFolder::ReadFileInfo(CDirItem &di)
{
di.FileInfo_WasRequested = true;
@@ -409,7 +427,71 @@ bool CFSFolder::ReadFileInfo(CDirItem &di)
di.FileInfo_Defined = true;
return true;
}
-#endif
+
+
+typedef struct
+{
+ LARGE_INTEGER CreationTime;
+ LARGE_INTEGER LastAccessTime;
+ LARGE_INTEGER LastWriteTime;
+ LARGE_INTEGER ChangeTime;
+ ULONG FileAttributes;
+ UInt32 Reserved; // it's expected for alignment
+}
+MY__FILE_BASIC_INFORMATION;
+
+
+typedef enum
+{
+ MY__FileDirectoryInformation = 1,
+ MY__FileFullDirectoryInformation,
+ MY__FileBothDirectoryInformation,
+ MY__FileBasicInformation
+}
+MY__FILE_INFORMATION_CLASS;
+
+
+typedef NTSTATUS (WINAPI * Func_NtQueryInformationFile)(
+ HANDLE handle, IO_STATUS_BLOCK *io,
+ void *ptr, LONG len, MY__FILE_INFORMATION_CLASS cls);
+
+#define MY__STATUS_SUCCESS 0
+
+static Func_NtQueryInformationFile f_NtQueryInformationFile;
+static bool g_NtQueryInformationFile_WasRequested = false;
+
+void CFSFolder::ReadChangeTime(CDirItem &di)
+{
+ di.ChangeTime_WasRequested = true;
+
+ if (!g_NtQueryInformationFile_WasRequested)
+ {
+ g_NtQueryInformationFile_WasRequested = true;
+ f_NtQueryInformationFile = (Func_NtQueryInformationFile)
+ My_GetProcAddress(::GetModuleHandleW(L"ntdll.dll"),
+ "NtQueryInformationFile");
+ }
+ if (!f_NtQueryInformationFile)
+ return;
+
+ NIO::CInFile file;
+ if (!file.Open_for_ReadAttributes(_path + GetRelPath(di)))
+ return;
+ MY__FILE_BASIC_INFORMATION fbi;
+ IO_STATUS_BLOCK IoStatusBlock;
+ const NTSTATUS status = f_NtQueryInformationFile(file.GetHandle(), &IoStatusBlock,
+ &fbi, sizeof(fbi), MY__FileBasicInformation);
+ if (status != MY__STATUS_SUCCESS)
+ return;
+ if (IoStatusBlock.Information != sizeof(fbi))
+ return;
+ di.ChangeTime.dwLowDateTime = fbi.ChangeTime.u.LowPart;
+ di.ChangeTime.dwHighDateTime = fbi.ChangeTime.u.HighPart;
+ di.ChangeTime_Defined = true;
+}
+
+#endif // FS_SHOW_LINKS_INFO
+
STDMETHODIMP CFSFolder::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
@@ -492,7 +574,14 @@ STDMETHODIMP CFSFolder::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
prop = fi.FileIndex;
#endif
break;
-
+
+ case kpidChangeTime:
+ if (!fi.ChangeTime_WasRequested)
+ ReadChangeTime(fi);
+ if (fi.ChangeTime_Defined)
+ prop = fi.ChangeTime;
+ break;
+
#endif
case kpidAttrib: prop = (UInt32)fi.Attrib; break;
diff --git a/CPP/7zip/UI/FileManager/FSFolder.h b/CPP/7zip/UI/FileManager/FSFolder.h
index fac1ef97..4f8c3449 100644..100755
--- a/CPP/7zip/UI/FileManager/FSFolder.h
+++ b/CPP/7zip/UI/FileManager/FSFolder.h
@@ -18,6 +18,7 @@ namespace NFsFolder {
class CFSFolder;
#define FS_SHOW_LINKS_INFO
+// #define FS_SHOW_CHANGE_TIME
struct CDirItem: public NWindows::NFile::NFind::CFileInfo
{
@@ -26,10 +27,13 @@ struct CDirItem: public NWindows::NFile::NFind::CFileInfo
#endif
#ifdef FS_SHOW_LINKS_INFO
+ FILETIME ChangeTime;
UInt64 FileIndex;
UInt32 NumLinks;
bool FileInfo_Defined;
bool FileInfo_WasRequested;
+ bool ChangeTime_Defined;
+ bool ChangeTime_WasRequested;
#endif
#ifndef UNDER_CE
@@ -158,6 +162,7 @@ private:
#ifdef FS_SHOW_LINKS_INFO
bool ReadFileInfo(CDirItem &di);
+ void ReadChangeTime(CDirItem &di);
#endif
public:
diff --git a/CPP/7zip/UI/FileManager/FSFolderCopy.cpp b/CPP/7zip/UI/FileManager/FSFolderCopy.cpp
index ff444b3b..ff444b3b 100644..100755
--- a/CPP/7zip/UI/FileManager/FSFolderCopy.cpp
+++ b/CPP/7zip/UI/FileManager/FSFolderCopy.cpp
diff --git a/CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp b/CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp
index a7873fe5..a7873fe5 100644..100755
--- a/CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp
+++ b/CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp
diff --git a/CPP/7zip/UI/FileManager/FileFolderPluginOpen.h b/CPP/7zip/UI/FileManager/FileFolderPluginOpen.h
index a1f2f104..a1f2f104 100644..100755
--- a/CPP/7zip/UI/FileManager/FileFolderPluginOpen.h
+++ b/CPP/7zip/UI/FileManager/FileFolderPluginOpen.h
diff --git a/CPP/7zip/UI/FileManager/FilePlugins.cpp b/CPP/7zip/UI/FileManager/FilePlugins.cpp
index 46000301..46000301 100644..100755
--- a/CPP/7zip/UI/FileManager/FilePlugins.cpp
+++ b/CPP/7zip/UI/FileManager/FilePlugins.cpp
diff --git a/CPP/7zip/UI/FileManager/FilePlugins.h b/CPP/7zip/UI/FileManager/FilePlugins.h
index 43b05f92..43b05f92 100644..100755
--- a/CPP/7zip/UI/FileManager/FilePlugins.h
+++ b/CPP/7zip/UI/FileManager/FilePlugins.h
diff --git a/CPP/7zip/UI/FileManager/FoldersPage.cpp b/CPP/7zip/UI/FileManager/FoldersPage.cpp
index d019bab8..d019bab8 100644..100755
--- a/CPP/7zip/UI/FileManager/FoldersPage.cpp
+++ b/CPP/7zip/UI/FileManager/FoldersPage.cpp
diff --git a/CPP/7zip/UI/FileManager/FoldersPage.h b/CPP/7zip/UI/FileManager/FoldersPage.h
index 71c7bfce..71c7bfce 100644..100755
--- a/CPP/7zip/UI/FileManager/FoldersPage.h
+++ b/CPP/7zip/UI/FileManager/FoldersPage.h
diff --git a/CPP/7zip/UI/FileManager/FoldersPage.rc b/CPP/7zip/UI/FileManager/FoldersPage.rc
index cb345ea6..cb345ea6 100644..100755
--- a/CPP/7zip/UI/FileManager/FoldersPage.rc
+++ b/CPP/7zip/UI/FileManager/FoldersPage.rc
diff --git a/CPP/7zip/UI/FileManager/FoldersPage2.rc b/CPP/7zip/UI/FileManager/FoldersPage2.rc
index 9b9276ef..9b9276ef 100644..100755
--- a/CPP/7zip/UI/FileManager/FoldersPage2.rc
+++ b/CPP/7zip/UI/FileManager/FoldersPage2.rc
diff --git a/CPP/7zip/UI/FileManager/FoldersPageRes.h b/CPP/7zip/UI/FileManager/FoldersPageRes.h
index ba9ab73e..ba9ab73e 100644..100755
--- a/CPP/7zip/UI/FileManager/FoldersPageRes.h
+++ b/CPP/7zip/UI/FileManager/FoldersPageRes.h
diff --git a/CPP/7zip/UI/FileManager/FormatUtils.cpp b/CPP/7zip/UI/FileManager/FormatUtils.cpp
index 2143c3f1..2143c3f1 100644..100755
--- a/CPP/7zip/UI/FileManager/FormatUtils.cpp
+++ b/CPP/7zip/UI/FileManager/FormatUtils.cpp
diff --git a/CPP/7zip/UI/FileManager/FormatUtils.h b/CPP/7zip/UI/FileManager/FormatUtils.h
index 993e8033..993e8033 100644..100755
--- a/CPP/7zip/UI/FileManager/FormatUtils.h
+++ b/CPP/7zip/UI/FileManager/FormatUtils.h
diff --git a/CPP/7zip/UI/FileManager/HelpUtils.cpp b/CPP/7zip/UI/FileManager/HelpUtils.cpp
index 2db95014..5cb78fc1 100644..100755
--- a/CPP/7zip/UI/FileManager/HelpUtils.cpp
+++ b/CPP/7zip/UI/FileManager/HelpUtils.cpp
@@ -12,7 +12,20 @@ void ShowHelpWindow(LPCSTR)
#else
+// #define USE_EXTERNAL_HELP
+
+#if defined(_MSC_VER)
+#endif
+
+#ifdef USE_EXTERNAL_HELP
+
+#include "../../../Windows/ProcessUtils.h"
+#include "../../../Windows/FileDir.h"
+#include "../../../Windows/FileName.h"
+
+#else
#include <HtmlHelp.h>
+#endif
#include "../../../Common/StringConvert.h"
@@ -25,8 +38,37 @@ void ShowHelpWindow(LPCSTR topicFile)
FString path = NWindows::NDLL::GetModuleDirPrefix();
path += kHelpFileName;
path += topicFile;
+ #ifdef USE_EXTERNAL_HELP
+ FString prog;
+
+ #ifdef UNDER_CE
+ prog = "\\Windows\\";
+ #else
+ if (!NWindows::NFile::NDir::GetWindowsDir(prog))
+ return;
+ NWindows::NFile::NName::NormalizeDirPathPrefix(prog);
+ #endif
+ prog += "hh.exe";
+
+ UString params;
+ params += '"';
+ params += fs2us(path);
+ params += '"';
+
+ NWindows::CProcess process;
+ const WRes wres = process.Create(fs2us(prog), params, NULL); // curDir);
+ if (wres != 0)
+ {
+ /*
+ HRESULT hres = HRESULT_FROM_WIN32(wres);
+ ErrorMessageHRESULT(hres, imageName);
+ return hres;
+ */
+ }
+ #else
// HWND hwnd = NULL;
HtmlHelp(NULL, GetSystemString(fs2us(path)), HH_DISPLAY_TOPIC, 0);
+ #endif
}
#endif
diff --git a/CPP/7zip/UI/FileManager/HelpUtils.h b/CPP/7zip/UI/FileManager/HelpUtils.h
index 90c5f7d1..90c5f7d1 100644..100755
--- a/CPP/7zip/UI/FileManager/HelpUtils.h
+++ b/CPP/7zip/UI/FileManager/HelpUtils.h
diff --git a/CPP/7zip/UI/FileManager/IFolder.h b/CPP/7zip/UI/FileManager/IFolder.h
index c5cff06e..c5cff06e 100644..100755
--- a/CPP/7zip/UI/FileManager/IFolder.h
+++ b/CPP/7zip/UI/FileManager/IFolder.h
diff --git a/CPP/7zip/UI/FileManager/Info.bmp b/CPP/7zip/UI/FileManager/Info.bmp
index d769a661..d769a661 100644..100755
--- a/CPP/7zip/UI/FileManager/Info.bmp
+++ b/CPP/7zip/UI/FileManager/Info.bmp
Binary files differ
diff --git a/CPP/7zip/UI/FileManager/Info2.bmp b/CPP/7zip/UI/FileManager/Info2.bmp
index af724d27..af724d27 100644..100755
--- a/CPP/7zip/UI/FileManager/Info2.bmp
+++ b/CPP/7zip/UI/FileManager/Info2.bmp
Binary files differ
diff --git a/CPP/7zip/UI/FileManager/LangPage.cpp b/CPP/7zip/UI/FileManager/LangPage.cpp
index 47e7894c..47e7894c 100644..100755
--- a/CPP/7zip/UI/FileManager/LangPage.cpp
+++ b/CPP/7zip/UI/FileManager/LangPage.cpp
diff --git a/CPP/7zip/UI/FileManager/LangPage.h b/CPP/7zip/UI/FileManager/LangPage.h
index b8062573..b8062573 100644..100755
--- a/CPP/7zip/UI/FileManager/LangPage.h
+++ b/CPP/7zip/UI/FileManager/LangPage.h
diff --git a/CPP/7zip/UI/FileManager/LangPage.rc b/CPP/7zip/UI/FileManager/LangPage.rc
index 164e2d30..164e2d30 100644..100755
--- a/CPP/7zip/UI/FileManager/LangPage.rc
+++ b/CPP/7zip/UI/FileManager/LangPage.rc
diff --git a/CPP/7zip/UI/FileManager/LangPageRes.h b/CPP/7zip/UI/FileManager/LangPageRes.h
index d7a39d75..d7a39d75 100644..100755
--- a/CPP/7zip/UI/FileManager/LangPageRes.h
+++ b/CPP/7zip/UI/FileManager/LangPageRes.h
diff --git a/CPP/7zip/UI/FileManager/LangUtils.cpp b/CPP/7zip/UI/FileManager/LangUtils.cpp
index 83d5aa70..83d5aa70 100644..100755
--- a/CPP/7zip/UI/FileManager/LangUtils.cpp
+++ b/CPP/7zip/UI/FileManager/LangUtils.cpp
diff --git a/CPP/7zip/UI/FileManager/LangUtils.h b/CPP/7zip/UI/FileManager/LangUtils.h
index d63a443c..d63a443c 100644..100755
--- a/CPP/7zip/UI/FileManager/LangUtils.h
+++ b/CPP/7zip/UI/FileManager/LangUtils.h
diff --git a/CPP/7zip/UI/FileManager/LinkDialog.cpp b/CPP/7zip/UI/FileManager/LinkDialog.cpp
index 07f1f061..07f1f061 100644..100755
--- a/CPP/7zip/UI/FileManager/LinkDialog.cpp
+++ b/CPP/7zip/UI/FileManager/LinkDialog.cpp
diff --git a/CPP/7zip/UI/FileManager/LinkDialog.h b/CPP/7zip/UI/FileManager/LinkDialog.h
index 56deec9d..56deec9d 100644..100755
--- a/CPP/7zip/UI/FileManager/LinkDialog.h
+++ b/CPP/7zip/UI/FileManager/LinkDialog.h
diff --git a/CPP/7zip/UI/FileManager/LinkDialog.rc b/CPP/7zip/UI/FileManager/LinkDialog.rc
index a9e220ba..a9e220ba 100644..100755
--- a/CPP/7zip/UI/FileManager/LinkDialog.rc
+++ b/CPP/7zip/UI/FileManager/LinkDialog.rc
diff --git a/CPP/7zip/UI/FileManager/LinkDialogRes.h b/CPP/7zip/UI/FileManager/LinkDialogRes.h
index 3f7b3f23..3f7b3f23 100644..100755
--- a/CPP/7zip/UI/FileManager/LinkDialogRes.h
+++ b/CPP/7zip/UI/FileManager/LinkDialogRes.h
diff --git a/CPP/7zip/UI/FileManager/ListViewDialog.cpp b/CPP/7zip/UI/FileManager/ListViewDialog.cpp
index a42e790b..a42e790b 100644..100755
--- a/CPP/7zip/UI/FileManager/ListViewDialog.cpp
+++ b/CPP/7zip/UI/FileManager/ListViewDialog.cpp
diff --git a/CPP/7zip/UI/FileManager/ListViewDialog.h b/CPP/7zip/UI/FileManager/ListViewDialog.h
index 00206afd..00206afd 100644..100755
--- a/CPP/7zip/UI/FileManager/ListViewDialog.h
+++ b/CPP/7zip/UI/FileManager/ListViewDialog.h
diff --git a/CPP/7zip/UI/FileManager/ListViewDialog.rc b/CPP/7zip/UI/FileManager/ListViewDialog.rc
index 4343b755..4343b755 100644..100755
--- a/CPP/7zip/UI/FileManager/ListViewDialog.rc
+++ b/CPP/7zip/UI/FileManager/ListViewDialog.rc
diff --git a/CPP/7zip/UI/FileManager/ListViewDialogRes.h b/CPP/7zip/UI/FileManager/ListViewDialogRes.h
index 9abdb9d2..9abdb9d2 100644..100755
--- a/CPP/7zip/UI/FileManager/ListViewDialogRes.h
+++ b/CPP/7zip/UI/FileManager/ListViewDialogRes.h
diff --git a/CPP/7zip/UI/FileManager/MenuPage.cpp b/CPP/7zip/UI/FileManager/MenuPage.cpp
index 05f24d71..32dabaec 100644..100755
--- a/CPP/7zip/UI/FileManager/MenuPage.cpp
+++ b/CPP/7zip/UI/FileManager/MenuPage.cpp
@@ -32,6 +32,7 @@ static const UInt32 kLangIDs[] =
IDX_SYSTEM_CASCADED_MENU,
IDX_SYSTEM_ICON_IN_MENU,
IDX_EXTRACT_ELIM_DUP,
+ IDT_SYSTEM_ZONE,
IDT_SYSTEM_CONTEXT_MENU_ITEMS
};
@@ -80,6 +81,16 @@ extern bool g_Is_Wow64;
#define KEY_WOW64_32KEY (0x0200)
#endif
+
+static void LoadLang_Spec(UString &s, UInt32 id, const char *eng)
+{
+ LangString(id, s);
+ if (s.IsEmpty())
+ s = eng;
+ s.RemoveChar(L'&');
+}
+
+
bool CMenuPage::OnInit()
{
_initMode = true;
@@ -176,6 +187,44 @@ bool CMenuPage::OnInit()
CheckButton(IDX_EXTRACT_ELIM_DUP, ci.ElimDup.Val);
_listView.Attach(GetItem(IDL_SYSTEM_OPTIONS));
+ _zoneCombo.Attach(GetItem(IDC_SYSTEM_ZONE));
+
+ {
+ unsigned wz = ci.WriteZone;
+ if (wz == (UInt32)(Int32)-1)
+ wz = 0;
+ for (unsigned i = 0; i <= 3; i++)
+ {
+ unsigned val = i;
+ UString s;
+ if (i == 3)
+ {
+ if (wz < 3)
+ break;
+ val = wz;
+ }
+ else
+ {
+ #define MY_IDYES 406
+ #define MY_IDNO 407
+ if (i == 0)
+ LoadLang_Spec(s, MY_IDNO, "No");
+ else if (i == 1)
+ LoadLang_Spec(s, MY_IDYES, "Yes");
+ else
+ LangString(IDT_ZONE_FOR_OFFICE, s);
+ }
+ if (s.IsEmpty())
+ s.Add_UInt32(val);
+ if (i == 0)
+ s.Insert(0, L"* ");
+ const int index = (int)_zoneCombo.AddString(s);
+ _zoneCombo.SetItemData(index, val);
+ if (val == wz)
+ _zoneCombo.SetCurSel(index);
+ }
+ }
+
const UInt32 newFlags = LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT;
_listView.SetExtendedListViewStyle(newFlags, newFlags);
@@ -266,7 +315,11 @@ LONG CMenuPage::OnApply()
#endif
- if (_cascaded_Changed || _menuIcons_Changed || _elimDup_Changed || _flags_Changed)
+ if (_cascaded_Changed
+ || _menuIcons_Changed
+ || _elimDup_Changed
+ || _writeZone_Changed
+ || _flags_Changed)
{
CContextMenuInfo ci;
ci.Cascaded.Val = IsButtonCheckedBool(IDX_SYSTEM_CASCADED_MENU);
@@ -278,6 +331,13 @@ LONG CMenuPage::OnApply()
ci.ElimDup.Val = IsButtonCheckedBool(IDX_EXTRACT_ELIM_DUP);
ci.ElimDup.Def = _elimDup_Changed;
+ {
+ int zoneIndex = (int)_zoneCombo.GetItemData_of_CurSel();
+ if (zoneIndex <= 0)
+ zoneIndex = -1;
+ ci.WriteZone = (UInt32)(Int32)zoneIndex;
+ }
+
ci.Flags = 0;
for (unsigned i = 0; i < ARRAY_SIZE(kMenuItems); i++)
@@ -321,6 +381,7 @@ bool CMenuPage::OnButtonClicked(int buttonID, HWND buttonHWND)
case IDX_SYSTEM_CASCADED_MENU: _cascaded_Changed = true; break;
case IDX_SYSTEM_ICON_IN_MENU: _menuIcons_Changed = true; break;
case IDX_EXTRACT_ELIM_DUP: _elimDup_Changed = true; break;
+ // case IDX_EXTRACT_WRITE_ZONE: _writeZone_Changed = true; break;
default:
return CPropertyPage::OnButtonClicked(buttonID, buttonHWND);
@@ -330,6 +391,19 @@ bool CMenuPage::OnButtonClicked(int buttonID, HWND buttonHWND)
return true;
}
+
+bool CMenuPage::OnCommand(int code, int itemID, LPARAM param)
+{
+ if (code == CBN_SELCHANGE && itemID == IDC_SYSTEM_ZONE)
+ {
+ _writeZone_Changed = true;
+ Changed();
+ return true;
+ }
+ return CPropertyPage::OnCommand(code, itemID, param);
+}
+
+
bool CMenuPage::OnNotify(UINT controlID, LPNMHDR lParam)
{
if (lParam->hwndFrom == HWND(_listView))
diff --git a/CPP/7zip/UI/FileManager/MenuPage.h b/CPP/7zip/UI/FileManager/MenuPage.h
index 3807d9dd..02aee6d7 100644..100755
--- a/CPP/7zip/UI/FileManager/MenuPage.h
+++ b/CPP/7zip/UI/FileManager/MenuPage.h
@@ -4,6 +4,7 @@
#define __MENU_PAGE_H
#include "../../../Windows/Control/PropertyPage.h"
+#include "../../../Windows/Control/ComboBox.h"
#include "../../../Windows/Control/ListView.h"
struct CShellDll
@@ -24,6 +25,7 @@ class CMenuPage: public NWindows::NControl::CPropertyPage
bool _cascaded_Changed;
bool _menuIcons_Changed;
bool _elimDup_Changed;
+ bool _writeZone_Changed;
bool _flags_Changed;
void Clear_MenuChanged()
@@ -31,6 +33,7 @@ class CMenuPage: public NWindows::NControl::CPropertyPage
_cascaded_Changed = false;
_menuIcons_Changed = false;
_elimDup_Changed = false;
+ _writeZone_Changed = false;
_flags_Changed = false;
}
@@ -39,6 +42,7 @@ class CMenuPage: public NWindows::NControl::CPropertyPage
#endif
NWindows::NControl::CListView _listView;
+ NWindows::NControl::CComboBox _zoneCombo;
virtual bool OnInit();
virtual void OnNotifyHelp();
@@ -46,6 +50,7 @@ class CMenuPage: public NWindows::NControl::CPropertyPage
virtual bool OnItemChanged(const NMLISTVIEW *info);
virtual LONG OnApply();
virtual bool OnButtonClicked(int buttonID, HWND buttonHWND);
+ virtual bool OnCommand(int code, int itemID, LPARAM param);
public:
};
diff --git a/CPP/7zip/UI/FileManager/MenuPage.rc b/CPP/7zip/UI/FileManager/MenuPage.rc
index fc211074..fc211074 100644..100755
--- a/CPP/7zip/UI/FileManager/MenuPage.rc
+++ b/CPP/7zip/UI/FileManager/MenuPage.rc
diff --git a/CPP/7zip/UI/FileManager/MenuPage2.rc b/CPP/7zip/UI/FileManager/MenuPage2.rc
index af86226d..4d1ba214 100644..100755
--- a/CPP/7zip/UI/FileManager/MenuPage2.rc
+++ b/CPP/7zip/UI/FileManager/MenuPage2.rc
@@ -1,6 +1,8 @@
#include "../GUI/ExtractDialogRes.h"
-#define y 82
+#define y 96
+
+#define zoneX 90
CAPTION "7-Zip"
BEGIN
@@ -10,8 +12,17 @@ BEGIN
CONTROL "Icons in context menu", IDX_SYSTEM_ICON_IN_MENU, MY_CHECKBOX, m, m + 42, xc, 10
CONTROL "Eliminate duplication of root folder", IDX_EXTRACT_ELIM_DUP, MY_CHECKBOX, m, m + 56, xc, 10
- LTEXT "Context menu items:", IDT_SYSTEM_CONTEXT_MENU_ITEMS, m, m + 70, xc, 8
+ LTEXT "Propagate Zone.Id stream:", IDT_SYSTEM_ZONE, m, m + 70, xc - zoneX, 8
+ COMBOBOX IDC_SYSTEM_ZONE, m + xc - zoneX, m + 70 - 2, zoneX, 50, MY_COMBO
+
+ LTEXT "Context menu items:", IDT_SYSTEM_CONTEXT_MENU_ITEMS, m, m + 84, xc, 8
CONTROL "List", IDL_SYSTEM_OPTIONS, "SysListView32",
LVS_REPORT | LVS_SINGLESEL | LVS_NOCOLUMNHEADER | WS_BORDER | WS_TABSTOP,
m, m + y, xc, yc - y
END
+
+
+STRINGTABLE
+BEGIN
+ IDT_ZONE_FOR_OFFICE "For Office files"
+END
diff --git a/CPP/7zip/UI/FileManager/MenuPageRes.h b/CPP/7zip/UI/FileManager/MenuPageRes.h
index ae0bf66d..e2cf7985 100644..100755
--- a/CPP/7zip/UI/FileManager/MenuPageRes.h
+++ b/CPP/7zip/UI/FileManager/MenuPageRes.h
@@ -8,4 +8,8 @@
#define IDX_SYSTEM_INTEGRATE_TO_MENU_2 2310
+#define IDT_SYSTEM_ZONE 3440
+#define IDT_ZONE_FOR_OFFICE 3441
+
#define IDL_SYSTEM_OPTIONS 100
+#define IDC_SYSTEM_ZONE 101
diff --git a/CPP/7zip/UI/FileManager/MessagesDialog.cpp b/CPP/7zip/UI/FileManager/MessagesDialog.cpp
index 41248277..41248277 100644..100755
--- a/CPP/7zip/UI/FileManager/MessagesDialog.cpp
+++ b/CPP/7zip/UI/FileManager/MessagesDialog.cpp
diff --git a/CPP/7zip/UI/FileManager/MessagesDialog.h b/CPP/7zip/UI/FileManager/MessagesDialog.h
index 5c017eb4..5c017eb4 100644..100755
--- a/CPP/7zip/UI/FileManager/MessagesDialog.h
+++ b/CPP/7zip/UI/FileManager/MessagesDialog.h
diff --git a/CPP/7zip/UI/FileManager/MessagesDialog.rc b/CPP/7zip/UI/FileManager/MessagesDialog.rc
index 49b73e84..49b73e84 100644..100755
--- a/CPP/7zip/UI/FileManager/MessagesDialog.rc
+++ b/CPP/7zip/UI/FileManager/MessagesDialog.rc
diff --git a/CPP/7zip/UI/FileManager/MessagesDialogRes.h b/CPP/7zip/UI/FileManager/MessagesDialogRes.h
index c8fffff6..c8fffff6 100644..100755
--- a/CPP/7zip/UI/FileManager/MessagesDialogRes.h
+++ b/CPP/7zip/UI/FileManager/MessagesDialogRes.h
diff --git a/CPP/7zip/UI/FileManager/Move.bmp b/CPP/7zip/UI/FileManager/Move.bmp
index eb5f20f9..eb5f20f9 100644..100755
--- a/CPP/7zip/UI/FileManager/Move.bmp
+++ b/CPP/7zip/UI/FileManager/Move.bmp
Binary files differ
diff --git a/CPP/7zip/UI/FileManager/Move2.bmp b/CPP/7zip/UI/FileManager/Move2.bmp
index 58679eff..58679eff 100644..100755
--- a/CPP/7zip/UI/FileManager/Move2.bmp
+++ b/CPP/7zip/UI/FileManager/Move2.bmp
Binary files differ
diff --git a/CPP/7zip/UI/FileManager/MyCom2.h b/CPP/7zip/UI/FileManager/MyCom2.h
index c45c2155..c45c2155 100644..100755
--- a/CPP/7zip/UI/FileManager/MyCom2.h
+++ b/CPP/7zip/UI/FileManager/MyCom2.h
diff --git a/CPP/7zip/UI/FileManager/MyLoadMenu.cpp b/CPP/7zip/UI/FileManager/MyLoadMenu.cpp
index d87dfe38..3973bb27 100644..100755
--- a/CPP/7zip/UI/FileManager/MyLoadMenu.cpp
+++ b/CPP/7zip/UI/FileManager/MyLoadMenu.cpp
@@ -380,7 +380,8 @@ void OnMenuActivating(HWND /* hWnd */, HMENU hMenu, int position)
kTimestampPrintLevel_MIN,
kTimestampPrintLevel_SEC,
// 1,2,3,4,5,6,
- kTimestampPrintLevel_NTFS
+ kTimestampPrintLevel_NTFS,
+ kTimestampPrintLevel_NS
};
unsigned last = kMenuID_Time;
diff --git a/CPP/7zip/UI/FileManager/MyLoadMenu.h b/CPP/7zip/UI/FileManager/MyLoadMenu.h
index 764bf7c7..764bf7c7 100644..100755
--- a/CPP/7zip/UI/FileManager/MyLoadMenu.h
+++ b/CPP/7zip/UI/FileManager/MyLoadMenu.h
diff --git a/CPP/7zip/UI/FileManager/MyWindowsNew.h b/CPP/7zip/UI/FileManager/MyWindowsNew.h
index 48a95359..48a95359 100644..100755
--- a/CPP/7zip/UI/FileManager/MyWindowsNew.h
+++ b/CPP/7zip/UI/FileManager/MyWindowsNew.h
diff --git a/CPP/7zip/UI/FileManager/NetFolder.cpp b/CPP/7zip/UI/FileManager/NetFolder.cpp
index a941e73d..a941e73d 100644..100755
--- a/CPP/7zip/UI/FileManager/NetFolder.cpp
+++ b/CPP/7zip/UI/FileManager/NetFolder.cpp
diff --git a/CPP/7zip/UI/FileManager/NetFolder.h b/CPP/7zip/UI/FileManager/NetFolder.h
index 151dd096..151dd096 100644..100755
--- a/CPP/7zip/UI/FileManager/NetFolder.h
+++ b/CPP/7zip/UI/FileManager/NetFolder.h
diff --git a/CPP/7zip/UI/FileManager/OpenCallback.cpp b/CPP/7zip/UI/FileManager/OpenCallback.cpp
index e2e03f5e..e2e03f5e 100644..100755
--- a/CPP/7zip/UI/FileManager/OpenCallback.cpp
+++ b/CPP/7zip/UI/FileManager/OpenCallback.cpp
diff --git a/CPP/7zip/UI/FileManager/OpenCallback.h b/CPP/7zip/UI/FileManager/OpenCallback.h
index 9aa5d43c..9aa5d43c 100644..100755
--- a/CPP/7zip/UI/FileManager/OpenCallback.h
+++ b/CPP/7zip/UI/FileManager/OpenCallback.h
diff --git a/CPP/7zip/UI/FileManager/OptionsDialog.cpp b/CPP/7zip/UI/FileManager/OptionsDialog.cpp
index c42e0f87..c42e0f87 100644..100755
--- a/CPP/7zip/UI/FileManager/OptionsDialog.cpp
+++ b/CPP/7zip/UI/FileManager/OptionsDialog.cpp
diff --git a/CPP/7zip/UI/FileManager/OverwriteDialog.cpp b/CPP/7zip/UI/FileManager/OverwriteDialog.cpp
index b455b14a..b455b14a 100644..100755
--- a/CPP/7zip/UI/FileManager/OverwriteDialog.cpp
+++ b/CPP/7zip/UI/FileManager/OverwriteDialog.cpp
diff --git a/CPP/7zip/UI/FileManager/OverwriteDialog.h b/CPP/7zip/UI/FileManager/OverwriteDialog.h
index 24e56cac..24e56cac 100644..100755
--- a/CPP/7zip/UI/FileManager/OverwriteDialog.h
+++ b/CPP/7zip/UI/FileManager/OverwriteDialog.h
diff --git a/CPP/7zip/UI/FileManager/OverwriteDialog.rc b/CPP/7zip/UI/FileManager/OverwriteDialog.rc
index 29f99122..29f99122 100644..100755
--- a/CPP/7zip/UI/FileManager/OverwriteDialog.rc
+++ b/CPP/7zip/UI/FileManager/OverwriteDialog.rc
diff --git a/CPP/7zip/UI/FileManager/OverwriteDialogRes.h b/CPP/7zip/UI/FileManager/OverwriteDialogRes.h
index b480ba16..b480ba16 100644..100755
--- a/CPP/7zip/UI/FileManager/OverwriteDialogRes.h
+++ b/CPP/7zip/UI/FileManager/OverwriteDialogRes.h
diff --git a/CPP/7zip/UI/FileManager/Panel.cpp b/CPP/7zip/UI/FileManager/Panel.cpp
index e8c0b947..f7cdb5b9 100644..100755
--- a/CPP/7zip/UI/FileManager/Panel.cpp
+++ b/CPP/7zip/UI/FileManager/Panel.cpp
@@ -20,6 +20,7 @@
#include "../Common/ArchiveName.h"
#include "../Common/CompressCall.h"
+#include "../Common/ZipRegistry.h"
#include "../Agent/IFolderArchive.h"
@@ -971,9 +972,13 @@ void CPanel::ExtractArchives()
outFolder += '*';
outFolder.Add_PathSepar();
+ CContextMenuInfo ci;
+ ci.Load();
+
::ExtractArchives(paths, outFolder
, true // showDialog
, false // elimDup
+ , ci.WriteZone
);
}
diff --git a/CPP/7zip/UI/FileManager/Panel.h b/CPP/7zip/UI/FileManager/Panel.h
index d1e4d244..4755678e 100644..100755
--- a/CPP/7zip/UI/FileManager/Panel.h
+++ b/CPP/7zip/UI/FileManager/Panel.h
@@ -244,6 +244,9 @@ struct CCopyToOptions
bool replaceAltStreamChars;
bool showErrorMessages;
+ bool NeedRegistryZone;
+ NExtract::NZoneIdMode::EEnum ZoneIdMode;
+
UString folder;
UStringVector hashMethods;
@@ -258,6 +261,8 @@ struct CCopyToOptions
includeAltStreams(true),
replaceAltStreamChars(false),
showErrorMessages(false),
+ NeedRegistryZone(true),
+ ZoneIdMode(NExtract::NZoneIdMode::kNone),
VirtFileSystemSpec(NULL),
VirtFileSystem(NULL)
{}
diff --git a/CPP/7zip/UI/FileManager/PanelCopy.cpp b/CPP/7zip/UI/FileManager/PanelCopy.cpp
index 7e1937c9..2ea3e3bd 100644..100755
--- a/CPP/7zip/UI/FileManager/PanelCopy.cpp
+++ b/CPP/7zip/UI/FileManager/PanelCopy.cpp
@@ -4,6 +4,8 @@
#include "../../../Common/MyException.h"
+#include "../Common/ZipRegistry.h"
+
#include "../GUI/HashGUI.h"
#include "ExtractCallback.h"
@@ -70,6 +72,15 @@ HRESULT CPanelCopyThread::ProcessVirt()
HRESULT result2;
+ {
+ CMyComPtr<IFolderSetZoneIdMode> setZoneMode;
+ FolderOperations.QueryInterface(IID_IFolderSetZoneIdMode, &setZoneMode);
+ if (setZoneMode)
+ {
+ RINOK(setZoneMode->SetZoneIdMode(options->ZoneIdMode));
+ }
+ }
+
if (options->testMode)
{
CMyComPtr<IArchiveFolder> archiveFolder;
@@ -126,6 +137,14 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &ind
UStringVector *messages,
bool &usePassword, UString &password)
{
+ if (options.NeedRegistryZone && !options.testMode)
+ {
+ CContextMenuInfo ci;
+ ci.Load();
+ if (ci.WriteZone != (UInt32)(Int32)-1)
+ options.ZoneIdMode = (NExtract::NZoneIdMode::EEnum)(int)(Int32)ci.WriteZone;
+ }
+
if (IsHashFolder())
{
if (!options.testMode)
@@ -221,7 +240,7 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &ind
title = LangString(titleID);
}
- UString progressWindowTitle ("7-Zip"); // LangString(IDS_APP_TITLE);
+ const UString progressWindowTitle ("7-Zip"); // LangString(IDS_APP_TITLE);
extracter.MainWindow = GetParent();
extracter.MainTitle = progressWindowTitle;
diff --git a/CPP/7zip/UI/FileManager/PanelCrc.cpp b/CPP/7zip/UI/FileManager/PanelCrc.cpp
index 1d483ca1..32948d85 100644..100755
--- a/CPP/7zip/UI/FileManager/PanelCrc.cpp
+++ b/CPP/7zip/UI/FileManager/PanelCrc.cpp
@@ -351,6 +351,7 @@ HRESULT CApp::CalculateCrc2(const UString &methodName)
options.streamMode = true;
options.showErrorMessages = true;
options.hashMethods.Add(methodName);
+ options.NeedRegistryZone = false;
UStringVector messages;
return srcPanel.CopyTo(options, indices, &messages);
diff --git a/CPP/7zip/UI/FileManager/PanelDrag.cpp b/CPP/7zip/UI/FileManager/PanelDrag.cpp
index af8799ca..af8799ca 100644..100755
--- a/CPP/7zip/UI/FileManager/PanelDrag.cpp
+++ b/CPP/7zip/UI/FileManager/PanelDrag.cpp
diff --git a/CPP/7zip/UI/FileManager/PanelFolderChange.cpp b/CPP/7zip/UI/FileManager/PanelFolderChange.cpp
index b91195f4..b91195f4 100644..100755
--- a/CPP/7zip/UI/FileManager/PanelFolderChange.cpp
+++ b/CPP/7zip/UI/FileManager/PanelFolderChange.cpp
diff --git a/CPP/7zip/UI/FileManager/PanelItemOpen.cpp b/CPP/7zip/UI/FileManager/PanelItemOpen.cpp
index ba54491d..17301b5e 100644..100755
--- a/CPP/7zip/UI/FileManager/PanelItemOpen.cpp
+++ b/CPP/7zip/UI/FileManager/PanelItemOpen.cpp
@@ -1403,7 +1403,7 @@ static THREAD_FUNC_DECL MyThreadFunction(void *param)
}
-
+/*
#if defined(_WIN32) && !defined(UNDER_CE)
static const FChar * const k_ZoneId_StreamName = FTEXT(":Zone.Identifier");
#endif
@@ -1441,6 +1441,7 @@ static bool WriteZoneFile(CFSTR fileName, const CByteBuffer &buf)
}
#endif
+*/
/*
class CBufSeqOutStream_WithFile:
@@ -1654,6 +1655,7 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, bo
password = fl.Password;
}
+ /*
#if defined(_WIN32) && !defined(UNDER_CE)
CByteBuffer zoneBuf;
#ifndef _UNICODE
@@ -1666,16 +1668,25 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, bo
ReadZoneFile(fl.FilePath + k_ZoneId_StreamName, zoneBuf);
}
#endif
+ */
CVirtFileSystem *virtFileSystemSpec = NULL;
CMyComPtr<ISequentialOutStream> virtFileSystem;
- bool isAltStream = IsItem_AltStream(index);
+ const bool isAltStream = IsItem_AltStream(index);
CCopyToOptions options;
options.includeAltStreams = true;
options.replaceAltStreamChars = isAltStream;
+ {
+ // CContextMenuInfo ci;
+ // ci.Load();
+ // if (ci.WriteZone != (UInt32)(Int32)-1)
+ // we use kAll when we unpack just one file.
+ options.ZoneIdMode = NExtract::NZoneIdMode::kAll;
+ options.NeedRegistryZone = false;
+ }
if (tryAsArchive)
{
@@ -1706,7 +1717,7 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, bo
options.folder = fs2us(tempDirNorm);
options.showErrorMessages = true;
- HRESULT result = CopyTo(options, indices, &messages, usePassword, password);
+ const HRESULT result = CopyTo(options, indices, &messages, usePassword, password);
if (_parentFolders.Size() > 0)
{
@@ -1759,6 +1770,7 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, bo
}
+ /*
#if defined(_WIN32) && !defined(UNDER_CE)
if (zoneBuf.Size() != 0)
{
@@ -1768,6 +1780,7 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, bo
}
}
#endif
+ */
if (tryAsArchive)
diff --git a/CPP/7zip/UI/FileManager/PanelItems.cpp b/CPP/7zip/UI/FileManager/PanelItems.cpp
index 33e44588..3cccf27e 100644..100755
--- a/CPP/7zip/UI/FileManager/PanelItems.cpp
+++ b/CPP/7zip/UI/FileManager/PanelItems.cpp
@@ -29,6 +29,7 @@ static bool GetColumnVisible(PROPID propID, bool isFsFolder)
switch (propID)
{
case kpidATime:
+ case kpidChangeTime:
case kpidAttrib:
case kpidPackSize:
case kpidINode:
@@ -56,6 +57,7 @@ static int GetColumnAlign(PROPID propID, VARTYPE varType)
case kpidCTime:
case kpidATime:
case kpidMTime:
+ case kpidChangeTime:
return LVCFMT_LEFT;
}
@@ -201,7 +203,7 @@ HRESULT CPanel::InitColumns()
for (i = 0; i < _listViewInfo.Columns.Size(); i++)
{
const CColumnInfo &columnInfo = _listViewInfo.Columns[i];
- int index = _columns.FindItem_for_PropID(columnInfo.PropID);
+ const int index = _columns.FindItem_for_PropID(columnInfo.PropID);
if (index >= 0)
{
CPropColumn &item = _columns[index];
@@ -650,7 +652,7 @@ HRESULT CPanel::RefreshListCtrl(const CSelectedState &state)
relPath += name;
if (relPath == state.FocusedName)
cursorIndex = listViewItemCount;
- if (state.SelectedNames.FindInSorted(relPath) >= 0)
+ if (state.SelectedNames.FindInSorted(relPath) != -1)
selected = true;
}
diff --git a/CPP/7zip/UI/FileManager/PanelKey.cpp b/CPP/7zip/UI/FileManager/PanelKey.cpp
index 3ab478eb..3ab478eb 100644..100755
--- a/CPP/7zip/UI/FileManager/PanelKey.cpp
+++ b/CPP/7zip/UI/FileManager/PanelKey.cpp
diff --git a/CPP/7zip/UI/FileManager/PanelListNotify.cpp b/CPP/7zip/UI/FileManager/PanelListNotify.cpp
index d2114f1c..d2114f1c 100644..100755
--- a/CPP/7zip/UI/FileManager/PanelListNotify.cpp
+++ b/CPP/7zip/UI/FileManager/PanelListNotify.cpp
diff --git a/CPP/7zip/UI/FileManager/PanelMenu.cpp b/CPP/7zip/UI/FileManager/PanelMenu.cpp
index 1a09a8f6..9e86951c 100644..100755
--- a/CPP/7zip/UI/FileManager/PanelMenu.cpp
+++ b/CPP/7zip/UI/FileManager/PanelMenu.cpp
@@ -111,7 +111,7 @@ static void AddPropertyString(PROPID propID, const wchar_t *nameBSTR,
val = ConvertSizeToString(v);
}
else
- ConvertPropertyToString2(val, prop, propID);
+ ConvertPropertyToString2(val, prop, propID, 9); // we send 9 - is ns precision
}
if (!val.IsEmpty())
diff --git a/CPP/7zip/UI/FileManager/PanelOperations.cpp b/CPP/7zip/UI/FileManager/PanelOperations.cpp
index e34e74f7..e34e74f7 100644..100755
--- a/CPP/7zip/UI/FileManager/PanelOperations.cpp
+++ b/CPP/7zip/UI/FileManager/PanelOperations.cpp
diff --git a/CPP/7zip/UI/FileManager/PanelSelect.cpp b/CPP/7zip/UI/FileManager/PanelSelect.cpp
index eab9e1ab..eab9e1ab 100644..100755
--- a/CPP/7zip/UI/FileManager/PanelSelect.cpp
+++ b/CPP/7zip/UI/FileManager/PanelSelect.cpp
diff --git a/CPP/7zip/UI/FileManager/PanelSort.cpp b/CPP/7zip/UI/FileManager/PanelSort.cpp
index d26acb70..d26acb70 100644..100755
--- a/CPP/7zip/UI/FileManager/PanelSort.cpp
+++ b/CPP/7zip/UI/FileManager/PanelSort.cpp
diff --git a/CPP/7zip/UI/FileManager/PanelSplitFile.cpp b/CPP/7zip/UI/FileManager/PanelSplitFile.cpp
index 00a0d801..00a0d801 100644..100755
--- a/CPP/7zip/UI/FileManager/PanelSplitFile.cpp
+++ b/CPP/7zip/UI/FileManager/PanelSplitFile.cpp
diff --git a/CPP/7zip/UI/FileManager/PasswordDialog.cpp b/CPP/7zip/UI/FileManager/PasswordDialog.cpp
index 6ead39c3..6ead39c3 100644..100755
--- a/CPP/7zip/UI/FileManager/PasswordDialog.cpp
+++ b/CPP/7zip/UI/FileManager/PasswordDialog.cpp
diff --git a/CPP/7zip/UI/FileManager/PasswordDialog.h b/CPP/7zip/UI/FileManager/PasswordDialog.h
index 339ebdaf..339ebdaf 100644..100755
--- a/CPP/7zip/UI/FileManager/PasswordDialog.h
+++ b/CPP/7zip/UI/FileManager/PasswordDialog.h
diff --git a/CPP/7zip/UI/FileManager/PasswordDialog.rc b/CPP/7zip/UI/FileManager/PasswordDialog.rc
index 90c57efa..90c57efa 100644..100755
--- a/CPP/7zip/UI/FileManager/PasswordDialog.rc
+++ b/CPP/7zip/UI/FileManager/PasswordDialog.rc
diff --git a/CPP/7zip/UI/FileManager/PasswordDialogRes.h b/CPP/7zip/UI/FileManager/PasswordDialogRes.h
index 1fe32e10..1fe32e10 100644..100755
--- a/CPP/7zip/UI/FileManager/PasswordDialogRes.h
+++ b/CPP/7zip/UI/FileManager/PasswordDialogRes.h
diff --git a/CPP/7zip/UI/FileManager/PluginInterface.h b/CPP/7zip/UI/FileManager/PluginInterface.h
index 37654a03..37654a03 100644..100755
--- a/CPP/7zip/UI/FileManager/PluginInterface.h
+++ b/CPP/7zip/UI/FileManager/PluginInterface.h
diff --git a/CPP/7zip/UI/FileManager/PluginLoader.h b/CPP/7zip/UI/FileManager/PluginLoader.h
index fed38d65..fed38d65 100644..100755
--- a/CPP/7zip/UI/FileManager/PluginLoader.h
+++ b/CPP/7zip/UI/FileManager/PluginLoader.h
diff --git a/CPP/7zip/UI/FileManager/ProgramLocation.cpp b/CPP/7zip/UI/FileManager/ProgramLocation.cpp
index 50ca5ca5..50ca5ca5 100644..100755
--- a/CPP/7zip/UI/FileManager/ProgramLocation.cpp
+++ b/CPP/7zip/UI/FileManager/ProgramLocation.cpp
diff --git a/CPP/7zip/UI/FileManager/ProgramLocation.h b/CPP/7zip/UI/FileManager/ProgramLocation.h
index 6bfb711e..6bfb711e 100644..100755
--- a/CPP/7zip/UI/FileManager/ProgramLocation.h
+++ b/CPP/7zip/UI/FileManager/ProgramLocation.h
diff --git a/CPP/7zip/UI/FileManager/ProgressDialog.cpp b/CPP/7zip/UI/FileManager/ProgressDialog.cpp
index b688a901..b688a901 100644..100755
--- a/CPP/7zip/UI/FileManager/ProgressDialog.cpp
+++ b/CPP/7zip/UI/FileManager/ProgressDialog.cpp
diff --git a/CPP/7zip/UI/FileManager/ProgressDialog.h b/CPP/7zip/UI/FileManager/ProgressDialog.h
index 35c182a8..35c182a8 100644..100755
--- a/CPP/7zip/UI/FileManager/ProgressDialog.h
+++ b/CPP/7zip/UI/FileManager/ProgressDialog.h
diff --git a/CPP/7zip/UI/FileManager/ProgressDialog.rc b/CPP/7zip/UI/FileManager/ProgressDialog.rc
index 55d99233..55d99233 100644..100755
--- a/CPP/7zip/UI/FileManager/ProgressDialog.rc
+++ b/CPP/7zip/UI/FileManager/ProgressDialog.rc
diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2.cpp b/CPP/7zip/UI/FileManager/ProgressDialog2.cpp
index 54273d0c..54273d0c 100644..100755
--- a/CPP/7zip/UI/FileManager/ProgressDialog2.cpp
+++ b/CPP/7zip/UI/FileManager/ProgressDialog2.cpp
diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2.h b/CPP/7zip/UI/FileManager/ProgressDialog2.h
index d8259d6a..d8259d6a 100644..100755
--- a/CPP/7zip/UI/FileManager/ProgressDialog2.h
+++ b/CPP/7zip/UI/FileManager/ProgressDialog2.h
diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2.rc b/CPP/7zip/UI/FileManager/ProgressDialog2.rc
index 4d0e0c7b..4d0e0c7b 100644..100755
--- a/CPP/7zip/UI/FileManager/ProgressDialog2.rc
+++ b/CPP/7zip/UI/FileManager/ProgressDialog2.rc
diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2Res.h b/CPP/7zip/UI/FileManager/ProgressDialog2Res.h
index 736c7179..736c7179 100644..100755
--- a/CPP/7zip/UI/FileManager/ProgressDialog2Res.h
+++ b/CPP/7zip/UI/FileManager/ProgressDialog2Res.h
diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2a.rc b/CPP/7zip/UI/FileManager/ProgressDialog2a.rc
index dc7d797f..dc7d797f 100644..100755
--- a/CPP/7zip/UI/FileManager/ProgressDialog2a.rc
+++ b/CPP/7zip/UI/FileManager/ProgressDialog2a.rc
diff --git a/CPP/7zip/UI/FileManager/ProgressDialogRes.h b/CPP/7zip/UI/FileManager/ProgressDialogRes.h
index cbf3beb2..cbf3beb2 100644..100755
--- a/CPP/7zip/UI/FileManager/ProgressDialogRes.h
+++ b/CPP/7zip/UI/FileManager/ProgressDialogRes.h
diff --git a/CPP/7zip/UI/FileManager/PropertyName.cpp b/CPP/7zip/UI/FileManager/PropertyName.cpp
index 838b6e3f..838b6e3f 100644..100755
--- a/CPP/7zip/UI/FileManager/PropertyName.cpp
+++ b/CPP/7zip/UI/FileManager/PropertyName.cpp
diff --git a/CPP/7zip/UI/FileManager/PropertyName.h b/CPP/7zip/UI/FileManager/PropertyName.h
index 4f0d6dc1..4f0d6dc1 100644..100755
--- a/CPP/7zip/UI/FileManager/PropertyName.h
+++ b/CPP/7zip/UI/FileManager/PropertyName.h
diff --git a/CPP/7zip/UI/FileManager/PropertyName.rc b/CPP/7zip/UI/FileManager/PropertyName.rc
index 5de5aeec..e16c526f 100644..100755
--- a/CPP/7zip/UI/FileManager/PropertyName.rc
+++ b/CPP/7zip/UI/FileManager/PropertyName.rc
@@ -97,4 +97,11 @@ BEGIN
IDS_PROP_READ_ONLY "Read-only"
IDS_PROP_OUT_NAME "Out Name"
IDS_PROP_COPY_LINK "Copy Link"
+ IDS_PROP_ARC_FILE_NAME "ArcFileName"
+ IDS_PROP_IS_HASH "IsHash"
+ IDS_PROP_CHANGE_TIME "Metadata Changed"
+ IDS_PROP_USER_ID "User ID"
+ IDS_PROP_GROUP_ID "Group ID"
+ IDS_PROP_DEVICE_MAJOR "Device Major"
+ IDS_PROP_DEVICE_MINOR "Device Minor"
END
diff --git a/CPP/7zip/UI/FileManager/PropertyNameRes.h b/CPP/7zip/UI/FileManager/PropertyNameRes.h
index 67f33902..e3d08db9 100644..100755
--- a/CPP/7zip/UI/FileManager/PropertyNameRes.h
+++ b/CPP/7zip/UI/FileManager/PropertyNameRes.h
@@ -93,3 +93,10 @@
#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
diff --git a/CPP/7zip/UI/FileManager/RegistryAssociations.cpp b/CPP/7zip/UI/FileManager/RegistryAssociations.cpp
index e48dbb44..e48dbb44 100644..100755
--- a/CPP/7zip/UI/FileManager/RegistryAssociations.cpp
+++ b/CPP/7zip/UI/FileManager/RegistryAssociations.cpp
diff --git a/CPP/7zip/UI/FileManager/RegistryAssociations.h b/CPP/7zip/UI/FileManager/RegistryAssociations.h
index 975c9d5f..975c9d5f 100644..100755
--- a/CPP/7zip/UI/FileManager/RegistryAssociations.h
+++ b/CPP/7zip/UI/FileManager/RegistryAssociations.h
diff --git a/CPP/7zip/UI/FileManager/RegistryPlugins.cpp b/CPP/7zip/UI/FileManager/RegistryPlugins.cpp
index 76a5787c..76a5787c 100644..100755
--- a/CPP/7zip/UI/FileManager/RegistryPlugins.cpp
+++ b/CPP/7zip/UI/FileManager/RegistryPlugins.cpp
diff --git a/CPP/7zip/UI/FileManager/RegistryPlugins.h b/CPP/7zip/UI/FileManager/RegistryPlugins.h
index dfa6de54..dfa6de54 100644..100755
--- a/CPP/7zip/UI/FileManager/RegistryPlugins.h
+++ b/CPP/7zip/UI/FileManager/RegistryPlugins.h
diff --git a/CPP/7zip/UI/FileManager/RegistryUtils.cpp b/CPP/7zip/UI/FileManager/RegistryUtils.cpp
index a2fc2011..a2fc2011 100644..100755
--- a/CPP/7zip/UI/FileManager/RegistryUtils.cpp
+++ b/CPP/7zip/UI/FileManager/RegistryUtils.cpp
diff --git a/CPP/7zip/UI/FileManager/RegistryUtils.h b/CPP/7zip/UI/FileManager/RegistryUtils.h
index b85d670f..b85d670f 100644..100755
--- a/CPP/7zip/UI/FileManager/RegistryUtils.h
+++ b/CPP/7zip/UI/FileManager/RegistryUtils.h
diff --git a/CPP/7zip/UI/FileManager/RootFolder.cpp b/CPP/7zip/UI/FileManager/RootFolder.cpp
index 84844c7d..84844c7d 100644..100755
--- a/CPP/7zip/UI/FileManager/RootFolder.cpp
+++ b/CPP/7zip/UI/FileManager/RootFolder.cpp
diff --git a/CPP/7zip/UI/FileManager/RootFolder.h b/CPP/7zip/UI/FileManager/RootFolder.h
index e2537837..e2537837 100644..100755
--- a/CPP/7zip/UI/FileManager/RootFolder.h
+++ b/CPP/7zip/UI/FileManager/RootFolder.h
diff --git a/CPP/7zip/UI/FileManager/SettingsPage.cpp b/CPP/7zip/UI/FileManager/SettingsPage.cpp
index 28687217..28687217 100644..100755
--- a/CPP/7zip/UI/FileManager/SettingsPage.cpp
+++ b/CPP/7zip/UI/FileManager/SettingsPage.cpp
diff --git a/CPP/7zip/UI/FileManager/SettingsPage.h b/CPP/7zip/UI/FileManager/SettingsPage.h
index f3f57a4b..f3f57a4b 100644..100755
--- a/CPP/7zip/UI/FileManager/SettingsPage.h
+++ b/CPP/7zip/UI/FileManager/SettingsPage.h
diff --git a/CPP/7zip/UI/FileManager/SettingsPage.rc b/CPP/7zip/UI/FileManager/SettingsPage.rc
index baab484a..baab484a 100644..100755
--- a/CPP/7zip/UI/FileManager/SettingsPage.rc
+++ b/CPP/7zip/UI/FileManager/SettingsPage.rc
diff --git a/CPP/7zip/UI/FileManager/SettingsPage2.rc b/CPP/7zip/UI/FileManager/SettingsPage2.rc
index cf907420..cf907420 100644..100755
--- a/CPP/7zip/UI/FileManager/SettingsPage2.rc
+++ b/CPP/7zip/UI/FileManager/SettingsPage2.rc
diff --git a/CPP/7zip/UI/FileManager/SettingsPageRes.h b/CPP/7zip/UI/FileManager/SettingsPageRes.h
index e990babc..e990babc 100644..100755
--- a/CPP/7zip/UI/FileManager/SettingsPageRes.h
+++ b/CPP/7zip/UI/FileManager/SettingsPageRes.h
diff --git a/CPP/7zip/UI/FileManager/SplitDialog.cpp b/CPP/7zip/UI/FileManager/SplitDialog.cpp
index 0c9fdd17..0c9fdd17 100644..100755
--- a/CPP/7zip/UI/FileManager/SplitDialog.cpp
+++ b/CPP/7zip/UI/FileManager/SplitDialog.cpp
diff --git a/CPP/7zip/UI/FileManager/SplitDialog.h b/CPP/7zip/UI/FileManager/SplitDialog.h
index 00aae658..00aae658 100644..100755
--- a/CPP/7zip/UI/FileManager/SplitDialog.h
+++ b/CPP/7zip/UI/FileManager/SplitDialog.h
diff --git a/CPP/7zip/UI/FileManager/SplitDialog.rc b/CPP/7zip/UI/FileManager/SplitDialog.rc
index 5a026e8a..5a026e8a 100644..100755
--- a/CPP/7zip/UI/FileManager/SplitDialog.rc
+++ b/CPP/7zip/UI/FileManager/SplitDialog.rc
diff --git a/CPP/7zip/UI/FileManager/SplitDialogRes.h b/CPP/7zip/UI/FileManager/SplitDialogRes.h
index 50584a14..50584a14 100644..100755
--- a/CPP/7zip/UI/FileManager/SplitDialogRes.h
+++ b/CPP/7zip/UI/FileManager/SplitDialogRes.h
diff --git a/CPP/7zip/UI/FileManager/SplitUtils.cpp b/CPP/7zip/UI/FileManager/SplitUtils.cpp
index 4b6235b3..4b6235b3 100644..100755
--- a/CPP/7zip/UI/FileManager/SplitUtils.cpp
+++ b/CPP/7zip/UI/FileManager/SplitUtils.cpp
diff --git a/CPP/7zip/UI/FileManager/SplitUtils.h b/CPP/7zip/UI/FileManager/SplitUtils.h
index 641dfe6b..641dfe6b 100644..100755
--- a/CPP/7zip/UI/FileManager/SplitUtils.h
+++ b/CPP/7zip/UI/FileManager/SplitUtils.h
diff --git a/CPP/7zip/UI/FileManager/StdAfx.cpp b/CPP/7zip/UI/FileManager/StdAfx.cpp
index d0feea85..d0feea85 100644..100755
--- a/CPP/7zip/UI/FileManager/StdAfx.cpp
+++ b/CPP/7zip/UI/FileManager/StdAfx.cpp
diff --git a/CPP/7zip/UI/FileManager/StdAfx.h b/CPP/7zip/UI/FileManager/StdAfx.h
index 0e6d4461..0e6d4461 100644..100755
--- a/CPP/7zip/UI/FileManager/StdAfx.h
+++ b/CPP/7zip/UI/FileManager/StdAfx.h
diff --git a/CPP/7zip/UI/FileManager/StringUtils.cpp b/CPP/7zip/UI/FileManager/StringUtils.cpp
index 04783992..04783992 100644..100755
--- a/CPP/7zip/UI/FileManager/StringUtils.cpp
+++ b/CPP/7zip/UI/FileManager/StringUtils.cpp
diff --git a/CPP/7zip/UI/FileManager/StringUtils.h b/CPP/7zip/UI/FileManager/StringUtils.h
index fc070de1..fc070de1 100644..100755
--- a/CPP/7zip/UI/FileManager/StringUtils.h
+++ b/CPP/7zip/UI/FileManager/StringUtils.h
diff --git a/CPP/7zip/UI/FileManager/SysIconUtils.cpp b/CPP/7zip/UI/FileManager/SysIconUtils.cpp
index b756dfcf..b756dfcf 100644..100755
--- a/CPP/7zip/UI/FileManager/SysIconUtils.cpp
+++ b/CPP/7zip/UI/FileManager/SysIconUtils.cpp
diff --git a/CPP/7zip/UI/FileManager/SysIconUtils.h b/CPP/7zip/UI/FileManager/SysIconUtils.h
index fde16e46..fde16e46 100644..100755
--- a/CPP/7zip/UI/FileManager/SysIconUtils.h
+++ b/CPP/7zip/UI/FileManager/SysIconUtils.h
diff --git a/CPP/7zip/UI/FileManager/SystemPage.cpp b/CPP/7zip/UI/FileManager/SystemPage.cpp
index a95999f2..a95999f2 100644..100755
--- a/CPP/7zip/UI/FileManager/SystemPage.cpp
+++ b/CPP/7zip/UI/FileManager/SystemPage.cpp
diff --git a/CPP/7zip/UI/FileManager/SystemPage.h b/CPP/7zip/UI/FileManager/SystemPage.h
index 765214cf..765214cf 100644..100755
--- a/CPP/7zip/UI/FileManager/SystemPage.h
+++ b/CPP/7zip/UI/FileManager/SystemPage.h
diff --git a/CPP/7zip/UI/FileManager/SystemPage.rc b/CPP/7zip/UI/FileManager/SystemPage.rc
index 3bb143a4..3bb143a4 100644..100755
--- a/CPP/7zip/UI/FileManager/SystemPage.rc
+++ b/CPP/7zip/UI/FileManager/SystemPage.rc
diff --git a/CPP/7zip/UI/FileManager/SystemPageRes.h b/CPP/7zip/UI/FileManager/SystemPageRes.h
index c8944482..c8944482 100644..100755
--- a/CPP/7zip/UI/FileManager/SystemPageRes.h
+++ b/CPP/7zip/UI/FileManager/SystemPageRes.h
diff --git a/CPP/7zip/UI/FileManager/Test.bmp b/CPP/7zip/UI/FileManager/Test.bmp
index ef85ba23..ef85ba23 100644..100755
--- a/CPP/7zip/UI/FileManager/Test.bmp
+++ b/CPP/7zip/UI/FileManager/Test.bmp
Binary files differ
diff --git a/CPP/7zip/UI/FileManager/Test2.bmp b/CPP/7zip/UI/FileManager/Test2.bmp
index 99b7dbf0..99b7dbf0 100644..100755
--- a/CPP/7zip/UI/FileManager/Test2.bmp
+++ b/CPP/7zip/UI/FileManager/Test2.bmp
Binary files differ
diff --git a/CPP/7zip/UI/FileManager/TextPairs.cpp b/CPP/7zip/UI/FileManager/TextPairs.cpp
index 6a989fcc..6a989fcc 100644..100755
--- a/CPP/7zip/UI/FileManager/TextPairs.cpp
+++ b/CPP/7zip/UI/FileManager/TextPairs.cpp
diff --git a/CPP/7zip/UI/FileManager/TextPairs.h b/CPP/7zip/UI/FileManager/TextPairs.h
index 0a71d044..0a71d044 100644..100755
--- a/CPP/7zip/UI/FileManager/TextPairs.h
+++ b/CPP/7zip/UI/FileManager/TextPairs.h
diff --git a/CPP/7zip/UI/FileManager/UpdateCallback100.cpp b/CPP/7zip/UI/FileManager/UpdateCallback100.cpp
index 67e70fb7..67e70fb7 100644..100755
--- a/CPP/7zip/UI/FileManager/UpdateCallback100.cpp
+++ b/CPP/7zip/UI/FileManager/UpdateCallback100.cpp
diff --git a/CPP/7zip/UI/FileManager/UpdateCallback100.h b/CPP/7zip/UI/FileManager/UpdateCallback100.h
index 7cbc11e3..7cbc11e3 100644..100755
--- a/CPP/7zip/UI/FileManager/UpdateCallback100.h
+++ b/CPP/7zip/UI/FileManager/UpdateCallback100.h
diff --git a/CPP/7zip/UI/FileManager/VerCtrl.cpp b/CPP/7zip/UI/FileManager/VerCtrl.cpp
index 4bb034f8..4bb034f8 100644..100755
--- a/CPP/7zip/UI/FileManager/VerCtrl.cpp
+++ b/CPP/7zip/UI/FileManager/VerCtrl.cpp
diff --git a/CPP/7zip/UI/FileManager/ViewSettings.cpp b/CPP/7zip/UI/FileManager/ViewSettings.cpp
index 0f87711f..0f87711f 100644..100755
--- a/CPP/7zip/UI/FileManager/ViewSettings.cpp
+++ b/CPP/7zip/UI/FileManager/ViewSettings.cpp
diff --git a/CPP/7zip/UI/FileManager/ViewSettings.h b/CPP/7zip/UI/FileManager/ViewSettings.h
index aeb68979..aeb68979 100644..100755
--- a/CPP/7zip/UI/FileManager/ViewSettings.h
+++ b/CPP/7zip/UI/FileManager/ViewSettings.h
diff --git a/CPP/7zip/UI/FileManager/makefile b/CPP/7zip/UI/FileManager/makefile
index dd2a2f20..dd2a2f20 100644..100755
--- a/CPP/7zip/UI/FileManager/makefile
+++ b/CPP/7zip/UI/FileManager/makefile
diff --git a/CPP/7zip/UI/FileManager/resource.h b/CPP/7zip/UI/FileManager/resource.h
index 98cb4fd4..98cb4fd4 100644..100755
--- a/CPP/7zip/UI/FileManager/resource.h
+++ b/CPP/7zip/UI/FileManager/resource.h
diff --git a/CPP/7zip/UI/FileManager/resource.rc b/CPP/7zip/UI/FileManager/resource.rc
index fc2c8408..fc2c8408 100644..100755
--- a/CPP/7zip/UI/FileManager/resource.rc
+++ b/CPP/7zip/UI/FileManager/resource.rc
diff --git a/CPP/7zip/UI/FileManager/resourceGui.h b/CPP/7zip/UI/FileManager/resourceGui.h
index 7c1b40e4..7c1b40e4 100644..100755
--- a/CPP/7zip/UI/FileManager/resourceGui.h
+++ b/CPP/7zip/UI/FileManager/resourceGui.h
diff --git a/CPP/7zip/UI/FileManager/resourceGui.rc b/CPP/7zip/UI/FileManager/resourceGui.rc
index f748e0bd..f748e0bd 100644..100755
--- a/CPP/7zip/UI/FileManager/resourceGui.rc
+++ b/CPP/7zip/UI/FileManager/resourceGui.rc
diff --git a/CPP/7zip/UI/GUI/7zG.exe.manifest b/CPP/7zip/UI/GUI/7zG.exe.manifest
index 39f516cd..39f516cd 100644..100755
--- a/CPP/7zip/UI/GUI/7zG.exe.manifest
+++ b/CPP/7zip/UI/GUI/7zG.exe.manifest
diff --git a/CPP/7zip/UI/GUI/BenchmarkDialog.cpp b/CPP/7zip/UI/GUI/BenchmarkDialog.cpp
index 71d28e8d..71d28e8d 100644..100755
--- a/CPP/7zip/UI/GUI/BenchmarkDialog.cpp
+++ b/CPP/7zip/UI/GUI/BenchmarkDialog.cpp
diff --git a/CPP/7zip/UI/GUI/BenchmarkDialog.h b/CPP/7zip/UI/GUI/BenchmarkDialog.h
index a280592e..a280592e 100644..100755
--- a/CPP/7zip/UI/GUI/BenchmarkDialog.h
+++ b/CPP/7zip/UI/GUI/BenchmarkDialog.h
diff --git a/CPP/7zip/UI/GUI/BenchmarkDialog.rc b/CPP/7zip/UI/GUI/BenchmarkDialog.rc
index 3e73e46d..3e73e46d 100644..100755
--- a/CPP/7zip/UI/GUI/BenchmarkDialog.rc
+++ b/CPP/7zip/UI/GUI/BenchmarkDialog.rc
diff --git a/CPP/7zip/UI/GUI/BenchmarkDialogRes.h b/CPP/7zip/UI/GUI/BenchmarkDialogRes.h
index b7d54b77..b7d54b77 100644..100755
--- a/CPP/7zip/UI/GUI/BenchmarkDialogRes.h
+++ b/CPP/7zip/UI/GUI/BenchmarkDialogRes.h
diff --git a/CPP/7zip/UI/GUI/CompressDialog.cpp b/CPP/7zip/UI/GUI/CompressDialog.cpp
index 16a35854..25b92194 100644..100755
--- a/CPP/7zip/UI/GUI/CompressDialog.cpp
+++ b/CPP/7zip/UI/GUI/CompressDialog.cpp
@@ -16,6 +16,7 @@
#include "../FileManager/BrowseDialog.h"
#include "../FileManager/FormatUtils.h"
#include "../FileManager/HelpUtils.h"
+#include "../FileManager/PropertyName.h"
#include "../FileManager/SplitUtils.h"
#include "../Explorer/MyMessages.h"
@@ -36,6 +37,9 @@ extern bool g_IsNT;
#include "ExtractRes.h"
#ifdef LANG
+
+// #define IDS_OPTIONS 2100
+
static const UInt32 kLangIDs[] =
{
IDT_COMPRESS_ARCHIVE,
@@ -49,6 +53,8 @@ static const UInt32 kLangIDs[] =
IDT_COMPRESS_THREADS,
IDT_COMPRESS_PARAMETERS,
+ IDB_COMPRESS_OPTIONS, // IDS_OPTIONS
+
IDG_COMPRESS_OPTIONS,
IDX_COMPRESS_SFX,
IDX_COMPRESS_SHARED,
@@ -57,11 +63,6 @@ static const UInt32 kLangIDs[] =
IDT_COMPRESS_MEMORY,
IDT_COMPRESS_MEMORY_DE,
- IDX_COMPRESS_NT_SYM_LINKS,
- IDX_COMPRESS_NT_HARD_LINKS,
- IDX_COMPRESS_NT_ALT_STREAMS,
- IDX_COMPRESS_NT_SECUR,
-
IDG_COMPRESS_ENCRYPTION,
IDT_COMPRESS_ENCRYPTION_METHOD,
IDX_COMPRESS_ENCRYPT_FILE_NAMES,
@@ -71,7 +72,7 @@ static const UInt32 kLangIDs[] =
IDX_PASSWORD_SHOW,
IDT_SPLIT_TO_VOLUMES,
- IDT_COMPRESS_PATH_MODE
+ IDT_COMPRESS_PATH_MODE,
};
#endif
@@ -89,8 +90,6 @@ static const UInt32 kLzmaMaxDictSize = (UInt32)15 << 28;
static LPCSTR const kExeExt = ".exe";
-#define k7zFormat "7z"
-
static const UInt32 g_Levels[] =
{
IDS_METHOD_STORE,
@@ -119,6 +118,8 @@ enum EMethodID
kSha1,
kCrc32,
kCrc64,
+ kGnu,
+ kPosix
};
static LPCSTR const kMethodsNames[] =
@@ -135,6 +136,8 @@ static LPCSTR const kMethodsNames[] =
, "SHA1"
, "CRC32"
, "CRC64"
+ , "GNU"
+ , "POSIX"
};
static const EMethodID g_7zMethods[] =
@@ -186,6 +189,12 @@ static const EMethodID g_SwfcMethods[] =
// kLZMA
};
+static const EMethodID g_TarMethods[] =
+{
+ kGnu,
+ kPosix
+};
+
static const EMethodID g_HashMethods[] =
{
kSha256
@@ -202,6 +211,13 @@ static const UInt32 kFF_EncryptFileNames = 1 << 4;
static const UInt32 kFF_MemUse = 1 << 5;
static const UInt32 kFF_SFX = 1 << 6;
+/*
+static const UInt32 kFF_Time_Win = 1 << 10;
+static const UInt32 kFF_Time_Unix = 1 << 11;
+static const UInt32 kFF_Time_DOS = 1 << 12;
+static const UInt32 kFF_Time_1ns = 1 << 13;
+*/
+
struct CFormatInfo
{
LPCSTR Name;
@@ -233,23 +249,26 @@ static const CFormatInfo g_Formats[] =
kFF_MultiThread | kFF_MemUse
},
{
- k7zFormat,
+ "7z",
(1 << 0) | (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9),
METHODS_PAIR(g_7zMethods),
kFF_Filter | kFF_Solid | kFF_MultiThread | kFF_Encrypt |
kFF_EncryptFileNames | kFF_MemUse | kFF_SFX
+ // | kFF_Time_Win
},
{
"Zip",
(1 << 0) | (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9),
METHODS_PAIR(g_ZipMethods),
kFF_MultiThread | kFF_Encrypt | kFF_MemUse
+ // | kFF_Time_Win | kFF_Time_Unix | kFF_Time_DOS
},
{
"GZip",
(1 << 1) | (1 << 5) | (1 << 7) | (1 << 9),
METHODS_PAIR(g_GZipMethods),
kFF_MemUse
+ // | kFF_Time_Unix
},
{
"BZip2",
@@ -272,14 +291,15 @@ static const CFormatInfo g_Formats[] =
{
"Tar",
(1 << 0),
- 0, NULL,
- 0
+ METHODS_PAIR(g_TarMethods),
+ // kFF_Time_Unix | kFF_Time_Win // | kFF_Time_1ns
},
{
"wim",
(1 << 0),
0, NULL,
0
+ // | kFF_Time_Win
},
{
"Hash",
@@ -335,22 +355,6 @@ static const UInt32 k_PathMode_IDs[] =
};
void AddComboItems(NControl::CComboBox &combo, const UInt32 *langIDs, unsigned numItems, const int *values, int curVal);
-bool GetBoolsVal(const CBoolPair &b1, const CBoolPair &b2);
-
-void CCompressDialog::CheckButton_TwoBools(UINT id, const CBoolPair &b1, const CBoolPair &b2)
-{
- CheckButton(id, GetBoolsVal(b1, b2));
-}
-
-void CCompressDialog::GetButton_Bools(UINT id, CBoolPair &b1, CBoolPair &b2)
-{
- bool val = IsButtonCheckedBool(id);
- bool oldVal = GetBoolsVal(b1, b2);
- if (val != oldVal)
- b1.Def = b2.Def = true;
- b1.Val = b2.Val = val;
-}
-
void CCompressDialog::SetMethods(const CObjectVector<CCodecInfoUser> &userCodecs)
{
@@ -375,12 +379,13 @@ void CCompressDialog::SetMethods(const CObjectVector<CCodecInfoUser> &userCodecs
}
}
-
+
bool CCompressDialog::OnInit()
{
#ifdef LANG
LangSetWindowText(*this, IDD_COMPRESS);
LangSetDlgItems(*this, kLangIDs, ARRAY_SIZE(kLangIDs));
+ // LangSetDlgItemText(*this, IDB_COMPRESS_OPTIONS, IDS_OPTIONS); // IDG_COMPRESS_OPTIONS
#endif
{
@@ -435,11 +440,6 @@ bool CCompressDialog::OnInit()
CheckButton(IDX_PASSWORD_SHOW, m_RegistryInfo.ShowPassword);
CheckButton(IDX_COMPRESS_ENCRYPT_FILE_NAMES, m_RegistryInfo.EncryptHeaders);
- CheckButton_TwoBools(IDX_COMPRESS_NT_SYM_LINKS, Info.SymLinks, m_RegistryInfo.SymLinks);
- CheckButton_TwoBools(IDX_COMPRESS_NT_HARD_LINKS, Info.HardLinks, m_RegistryInfo.HardLinks);
- CheckButton_TwoBools(IDX_COMPRESS_NT_ALT_STREAMS, Info.AltStreams, m_RegistryInfo.AltStreams);
- CheckButton_TwoBools(IDX_COMPRESS_NT_SECUR, Info.NtSecurity, m_RegistryInfo.NtSecurity);
-
UpdatePasswordControl();
{
@@ -490,7 +490,7 @@ bool CCompressDialog::OnInit()
CheckButton(IDX_COMPRESS_SHARED, Info.OpenShareForWrite);
CheckButton(IDX_COMPRESS_DEL, Info.DeleteAfterCompressing);
- FormatChanged();
+ FormatChanged(false); // isChanged
// OnButtonSFX();
@@ -552,6 +552,13 @@ bool CCompressDialog::OnButtonClicked(int buttonID, HWND buttonHWND)
UpdatePasswordControl();
return true;
}
+ case IDB_COMPRESS_OPTIONS:
+ {
+ COptionsDialog dialog(this);
+ if (dialog.Create(*this) == IDOK)
+ ShowOptionsString();
+ return true;
+ }
}
return CModalDialog::OnButtonClicked(buttonID, buttonHWND);
}
@@ -588,8 +595,44 @@ void CCompressDialog::EnableMultiCombo(unsigned id)
EnableItem(id, enable);
}
+static LRESULT ComboBox_AddStringAscii(NControl::CComboBox &cb, const char *s);
+static void FormatOptions_To_String(const NCompression::CFormatOptions &fo, AString &s);
-void CCompressDialog::FormatChanged()
+static void Combine_Two_BoolPairs(const CBoolPair &b1, const CBoolPair &b2, CBool1 &res)
+{
+ if (!b1.Def && b2.Def)
+ res.Val = b2.Val;
+ else
+ res.Val = b1.Val;
+}
+
+#define SET_GUI_BOOL(name) \
+ Combine_Two_BoolPairs(Info. ## name, m_RegistryInfo. ## name, name)
+
+
+static void Set_Final_BoolPairs(
+ const CBool1 &gui,
+ CBoolPair &cmd,
+ CBoolPair &reg)
+{
+ if (!cmd.Def)
+ {
+ reg.Val = gui.Val;
+ reg.Def = gui.Val;
+ }
+ if (gui.Supported)
+ {
+ cmd.Val = gui.Val;
+ cmd.Def = gui.Val;
+ }
+ else
+ cmd.Init();
+}
+
+#define SET_FINAL_BOOL_PAIRS(name) \
+ Set_Final_BoolPairs(name, Info. ## name, m_RegistryInfo. ## name)
+
+void CCompressDialog::FormatChanged(bool isChanged)
{
SetLevel();
SetSolidBlockSize();
@@ -615,18 +658,26 @@ void CCompressDialog::FormatChanged()
CheckSFXControlsEnable();
{
- const CArcInfoEx &ai = Get_ArcInfoEx();
-
- ShowItem_Bool(IDX_COMPRESS_NT_SYM_LINKS, ai.Flags_SymLinks());
- ShowItem_Bool(IDX_COMPRESS_NT_HARD_LINKS, ai.Flags_HardLinks());
- ShowItem_Bool(IDX_COMPRESS_NT_ALT_STREAMS, ai.Flags_AltStreams());
- ShowItem_Bool(IDX_COMPRESS_NT_SECUR, ai.Flags_NtSecure());
+ if (!isChanged)
+ {
+ SET_GUI_BOOL (SymLinks);
+ SET_GUI_BOOL (HardLinks);
+ SET_GUI_BOOL (AltStreams);
+ SET_GUI_BOOL (NtSecurity);
+ SET_GUI_BOOL (PreserveATime);
+ }
- ShowItem_Bool(IDG_COMPRESS_NTFS,
- ai.Flags_SymLinks()
- || ai.Flags_HardLinks()
- || ai.Flags_AltStreams()
- || ai.Flags_NtSecure());
+ PreserveATime.Supported = true;
+
+ {
+ const CArcInfoEx &ai = Get_ArcInfoEx();
+ SymLinks.Supported = ai.Flags_SymLinks();
+ HardLinks.Supported = ai.Flags_HardLinks();
+ AltStreams.Supported = ai.Flags_AltStreams();
+ NtSecurity.Supported = ai.Flags_NtSecurity();
+ }
+
+ ShowOptionsString();
}
// CheckVolumeEnable();
@@ -821,7 +872,7 @@ void SetErrorMessage_MemUsage(UString &s, UInt64 reqSize, UInt64 ramSize, UInt64
s.Add_LF();
s.Add_LF();
- s += LangString(IDS_MEM_ERROR);
+ AddLangString(s, IDS_MEM_ERROR);
}
@@ -933,17 +984,32 @@ void CCompressDialog::OnOK()
Info.EncryptHeaders = IsButtonCheckedBool(IDX_COMPRESS_ENCRYPT_FILE_NAMES);
- GetButton_Bools(IDX_COMPRESS_NT_SYM_LINKS, Info.SymLinks, m_RegistryInfo.SymLinks);
- GetButton_Bools(IDX_COMPRESS_NT_HARD_LINKS, Info.HardLinks, m_RegistryInfo.HardLinks);
- GetButton_Bools(IDX_COMPRESS_NT_ALT_STREAMS, Info.AltStreams, m_RegistryInfo.AltStreams);
- GetButton_Bools(IDX_COMPRESS_NT_SECUR, Info.NtSecurity, m_RegistryInfo.NtSecurity);
+ /* (Info) is for saving to registry:
+ (CBoolPair::Val) will be set as (false), if it was (false)
+ in registry at dialog creation, and user didn't click checkbox.
+ in another case (CBoolPair::Val) will be set as (true) */
{
- const CArcInfoEx &ai = Get_ArcInfoEx();
- if (!ai.Flags_SymLinks()) Info.SymLinks.Val = false;
- if (!ai.Flags_HardLinks()) Info.HardLinks.Val = false;
- if (!ai.Flags_AltStreams()) Info.AltStreams.Val = false;
- if (!ai.Flags_NtSecure()) Info.NtSecurity.Val = false;
+ /* Info properties could be for another archive types.
+ so we disable unsupported properties in Info */
+ // const CArcInfoEx &ai = Get_ArcInfoEx();
+
+ SET_FINAL_BOOL_PAIRS (SymLinks);
+ SET_FINAL_BOOL_PAIRS (HardLinks);
+ SET_FINAL_BOOL_PAIRS (AltStreams);
+ SET_FINAL_BOOL_PAIRS (NtSecurity);
+
+ SET_FINAL_BOOL_PAIRS (PreserveATime);
+ }
+
+ {
+ const NCompression::CFormatOptions &fo = Get_FormatOptions();
+
+ Info.TimePrec = fo.TimePrec;
+ Info.MTime = fo.MTime;
+ Info.CTime = fo.CTime;
+ Info.ATime = fo.ATime;
+ Info.SetArcMTime = fo.SetArcMTime;
}
m_Params.GetText(Info.Options);
@@ -1031,7 +1097,7 @@ bool CCompressDialog::OnCommand(int code, int itemID, LPARAM lParam)
{
const bool isSFX = IsSFX();
SaveOptionsInMem();
- FormatChanged();
+ FormatChanged(true); // isChanged
SetArchiveName2(isSFX);
return true;
}
@@ -1057,6 +1123,7 @@ bool CCompressDialog::OnCommand(int code, int itemID, LPARAM lParam)
SetMemoryUsage();
if (Get_ArcInfoEx().Flags_HashHandler())
SetArchiveName2(false);
+
return true;
}
@@ -1188,6 +1255,7 @@ void CCompressDialog::SetArchiveName(const UString &name)
m_ArchivePath.SetText(fileName);
}
+
int CCompressDialog::FindRegistryFormat(const UString &name)
{
FOR_VECTOR (i, m_RegistryInfo.Formats)
@@ -1199,7 +1267,8 @@ int CCompressDialog::FindRegistryFormat(const UString &name)
return -1;
}
-int CCompressDialog::FindRegistryFormatAlways(const UString &name)
+
+unsigned CCompressDialog::FindRegistryFormat_Always(const UString &name)
{
int index = FindRegistryFormat(name);
if (index < 0)
@@ -1211,6 +1280,14 @@ int CCompressDialog::FindRegistryFormatAlways(const UString &name)
return index;
}
+
+NCompression::CFormatOptions &CCompressDialog::Get_FormatOptions()
+{
+ const CArcInfoEx &ai = Get_ArcInfoEx();
+ return m_RegistryInfo.Formats[FindRegistryFormat_Always(ai.Name)];
+}
+
+
int CCompressDialog::GetStaticFormatIndex()
{
const CArcInfoEx &ai = Get_ArcInfoEx();
@@ -1293,8 +1370,11 @@ void CCompressDialog::SetMethod2(int keepMethodId)
const CArcInfoEx &ai = Get_ArcInfoEx();
if (GetLevel() == 0 && !ai.Flags_HashHandler())
{
- MethodChanged();
- return;
+ if (!ai.Is_Tar())
+ {
+ MethodChanged();
+ return;
+ }
}
UString defaultMethod;
{
@@ -1308,7 +1388,7 @@ void CCompressDialog::SetMethod2(int keepMethodId)
const bool isSfx = IsSFX();
bool weUseSameMethod = false;
- const bool is7z = ai.Name.IsEqualTo_Ascii_NoCase("7z");
+ const bool is7z = ai.Is_7z();
for (unsigned m = 0;; m++)
{
@@ -1367,12 +1447,12 @@ void CCompressDialog::SetMethod2(int keepMethodId)
bool CCompressDialog::IsZipFormat()
{
- return Get_ArcInfoEx().Name.IsEqualTo_Ascii_NoCase("zip");
+ return Get_ArcInfoEx().Is_Zip();
}
bool CCompressDialog::IsXzFormat()
{
- return Get_ArcInfoEx().Name.IsEqualTo_Ascii_NoCase("xz");
+ return Get_ArcInfoEx().Is_Xz();
}
void CCompressDialog::SetEncryptionMethod()
@@ -1380,13 +1460,13 @@ void CCompressDialog::SetEncryptionMethod()
_encryptionMethod.ResetContent();
_default_encryptionMethod_Index = -1;
const CArcInfoEx &ai = Get_ArcInfoEx();
- if (ai.Name.IsEqualTo_Ascii_NoCase("7z"))
+ if (ai.Is_7z())
{
ComboBox_AddStringAscii(_encryptionMethod, "AES-256");
_encryptionMethod.SetCurSel(0);
_default_encryptionMethod_Index = 0;
}
- else if (ai.Name.IsEqualTo_Ascii_NoCase("zip"))
+ else if (ai.Is_Zip())
{
int index = FindRegistryFormat(ai.Name);
UString encryptionMethod;
@@ -1929,7 +2009,7 @@ void CCompressDialog::SetSolidBlockSize2()
}
}
- const bool is7z = ai.Name.IsEqualTo_Ascii_NoCase("7z");
+ const bool is7z = ai.Is_7z();
const UInt64 cs = Get_Lzma2_ChunkSize(dict);
@@ -2549,11 +2629,16 @@ void CCompressDialog::SetParams()
void CCompressDialog::SaveOptionsInMem()
{
+ /* these options are for (Info.FormatIndex).
+ If it's called just after format changing,
+ then it's format that was selected before format changing
+ So we store previous format properties */
+
m_Params.GetText(Info.Options);
Info.Options.Trim();
const CArcInfoEx &ai = (*ArcFormats)[Info.FormatIndex];
- const int index = FindRegistryFormatAlways(ai.Name);
+ const unsigned index = FindRegistryFormat_Always(ai.Name);
NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index];
fo.Options = Info.Options;
fo.Level = GetLevelSpec();
@@ -2587,7 +2672,512 @@ void CCompressDialog::SaveOptionsInMem()
fo.MemUse = Get_MemUse_Spec();
}
+
unsigned CCompressDialog::GetFormatIndex()
{
return (unsigned)m_Format.GetItemData_of_CurSel();
}
+
+
+
+static void AddText_from_BoolPair(AString &s, const char *name, const CBoolPair &bp)
+{
+ if (bp.Def)
+ {
+ s.Add_OptSpaced(name);
+ if (!bp.Val)
+ s += "-";
+ }
+ /*
+ else if (bp.Val)
+ {
+ s.Add_OptSpaced("[");
+ s += name;
+ s += "]";
+ }
+ */
+}
+
+
+static void AddText_from_Bool1(AString &s, const char *name, const CBool1 &b)
+{
+ if (b.Supported && b.Val)
+ s.Add_OptSpaced(name);
+}
+
+
+void CCompressDialog::ShowOptionsString()
+{
+ NCompression::CFormatOptions &fo = Get_FormatOptions();
+
+ AString s;
+ if (fo.TimePrec != -1)
+ {
+ s.Add_OptSpaced("tp");
+ s.Add_UInt32(fo.TimePrec);
+ }
+ AddText_from_BoolPair(s, "tm", fo.MTime);
+ AddText_from_BoolPair(s, "tc", fo.CTime);
+ AddText_from_BoolPair(s, "ta", fo.ATime);
+ AddText_from_BoolPair(s, "-stl", fo.SetArcMTime);
+
+ // const CArcInfoEx &ai = Get_ArcInfoEx();
+ AddText_from_Bool1(s, "SL", SymLinks);
+ AddText_from_Bool1(s, "HL", HardLinks);
+ AddText_from_Bool1(s, "AS", AltStreams);
+ AddText_from_Bool1(s, "Sec", NtSecurity);
+
+ // AddText_from_Bool1(s, "Preserve", PreserveATime);
+
+ SetItemText(IDT_COMPRESS_OPTIONS, GetUnicodeString(s));
+}
+
+
+
+
+
+// ---------- OPTIONS ----------
+
+
+void COptionsDialog::CheckButton_Bool1(UINT id, const CBool1 &b1)
+{
+ CheckButton(id, b1.Val);
+}
+
+void COptionsDialog::GetButton_Bool1(UINT id, CBool1 &b1)
+{
+ b1.Val = IsButtonCheckedBool(id);
+}
+
+
+void COptionsDialog::CheckButton_BoolBox(
+ bool supported, const CBoolPair &b2, CBoolBox &bb)
+{
+ const bool isSet = b2.Def;
+ const bool val = isSet ? b2.Val : bb.DefaultVal;
+
+ bb.IsSupported = supported;
+
+ CheckButton (bb.Set_Id, isSet);
+ ShowItem_Bool (bb.Set_Id, supported);
+ CheckButton (bb.Id, val);
+ EnableItem (bb.Id, isSet);
+ ShowItem_Bool (bb.Id, supported);
+}
+
+void COptionsDialog::GetButton_BoolBox(CBoolBox &bb)
+{
+ // we save value for invisible buttons too
+ bb.BoolPair.Val = IsButtonCheckedBool (bb.Id);
+ bb.BoolPair.Def = IsButtonCheckedBool (bb.Set_Id);
+}
+
+
+void COptionsDialog::Store_TimeBoxes()
+{
+ TimePrec = GetPrecSpec();
+ GetButton_BoolBox (MTime);
+ GetButton_BoolBox (CTime);
+ GetButton_BoolBox (ATime);
+ GetButton_BoolBox (ZTime);
+}
+
+
+UInt32 COptionsDialog::GetComboValue(NWindows::NControl::CComboBox &c, int defMax)
+{
+ if (c.GetCount() <= defMax)
+ return (UInt32)(Int32)-1;
+ return (UInt32)c.GetItemData_of_CurSel();
+}
+
+static const unsigned kTimePrec_Win = 0;
+static const unsigned kTimePrec_Unix = 1;
+static const unsigned kTimePrec_DOS = 2;
+static const unsigned kTimePrec_1ns = 3;
+
+static void AddTimeOption(UString &s, UInt32 val, const UString &unit, const char *sys = NULL)
+{
+ // s += " : ";
+ {
+ AString s2;
+ s2.Add_UInt32(val);
+ s += s2;
+ }
+ s.Add_Space();
+ s += unit;
+ if (sys)
+ {
+ s += " : ";
+ s += sys;
+ }
+}
+
+int COptionsDialog::AddPrec(unsigned prec, bool isDefault)
+{
+ UString s;
+ UInt32 writePrec = prec;
+ if (isDefault)
+ {
+ // s += "* ";
+ // writePrec = (UInt32)(Int32)-1;
+ }
+ if (prec == kTimePrec_Win) AddTimeOption(s, 100, NsString, "Windows");
+ else if (prec == kTimePrec_Unix) AddTimeOption(s, 1, SecString, "Unix");
+ else if (prec == kTimePrec_DOS) AddTimeOption(s, 2, SecString, "DOS");
+ else if (prec == kTimePrec_1ns) AddTimeOption(s, 1, NsString, "Linux");
+ else if (prec == k_PropVar_TimePrec_Base) AddTimeOption(s, 1, SecString);
+ else if (prec >= k_PropVar_TimePrec_Base)
+ {
+ UInt32 d = 1;
+ for (unsigned i = prec; i < k_PropVar_TimePrec_Base + 9; i++)
+ d *= 10;
+ AddTimeOption(s, d, NsString);
+ }
+ else
+ s.Add_UInt32(prec);
+ const int index = (int)m_Prec.AddString(s);
+ m_Prec.SetItemData(index, writePrec);
+ return index;
+}
+
+
+void COptionsDialog::SetPrec()
+{
+ // const CFormatInfo &fi = g_Formats[cd->GetStaticFormatIndex()];
+ const CArcInfoEx &ai = cd->Get_ArcInfoEx();
+
+ // UInt32 flags = fi.Flags;
+
+ UInt32 flags = ai.Get_TimePrecFlags();
+ UInt32 defaultPrec = ai.Get_DefaultTimePrec();
+ if (defaultPrec != 0)
+ flags |= ((UInt32)1 << defaultPrec);
+
+ // const NCompression::CFormatOptions &fo = cd->Get_FormatOptions();
+
+ // unsigned defaultPrec = kTimePrec_Win;
+
+ if (ai.Is_GZip())
+ defaultPrec = kTimePrec_Unix;
+
+ {
+ UString s;
+ s += GetNameOfProperty(kpidType, L"type");
+ s += ": ";
+ s += ai.Name;
+ if (ai.Is_Tar())
+ {
+ const int methodID = cd->GetMethodID();
+
+ // for debug
+ // defaultPrec = kTimePrec_Unix;
+ // flags = (UInt32)1 << kTimePrec_Unix;
+
+ s += ":";
+ if (methodID >= 0 && (unsigned)methodID < ARRAY_SIZE(kMethodsNames))
+ s += kMethodsNames[methodID];
+ if (methodID == kPosix)
+ {
+ // for debug
+ // flags |= (UInt32)1 << kTimePrec_Win;
+ // flags |= (UInt32)1 << kTimePrec_1ns;
+ }
+ }
+ else
+ {
+ // if (is_for_MethodChanging) return;
+ }
+
+ SetItemText(IDT_COMPRESS_TIME_INFO, s);
+ }
+
+ m_Prec.ResetContent();
+ _auto_Prec = defaultPrec;
+
+ unsigned selectedPrec = defaultPrec;
+ {
+ // if (TimePrec >= kTimePrec_Win && TimePrec <= kTimePrec_DOS)
+ if ((Int32)TimePrec >= 0)
+ selectedPrec = TimePrec;
+ }
+
+ int curSel = -1;
+ int defaultPrecIndex = -1;
+ for (unsigned prec = 0;
+ // prec <= k_PropVar_TimePrec_HighPrec;
+ prec <= k_PropVar_TimePrec_1ns;
+ prec++)
+ {
+ if (((flags >> prec) & 1) == 0)
+ continue;
+ const bool isDefault = (defaultPrec == prec);
+ const int index = AddPrec(prec, isDefault);
+ if (isDefault)
+ defaultPrecIndex = index;
+ if (selectedPrec == prec)
+ curSel = index;
+ }
+
+ if (curSel < 0 && selectedPrec > kTimePrec_DOS)
+ curSel = AddPrec(selectedPrec, false); // isDefault
+ if (curSel < 0)
+ curSel = defaultPrecIndex;
+ if (curSel >= 0)
+ m_Prec.SetCurSel(curSel);
+
+ {
+ const bool isSet = IsSet_TimePrec();
+ const int count = m_Prec.GetCount();
+ const bool showPrec = (count != 0);
+ ShowItem_Bool(IDC_COMPRESS_TIME_PREC, showPrec);
+ ShowItem_Bool(IDT_COMPRESS_TIME_PREC, showPrec);
+ EnableItem(IDC_COMPRESS_TIME_PREC, isSet && (count > 1));
+
+ CheckButton(IDX_COMPRESS_PREC_SET, isSet);
+ const bool setIsSupported = isSet || (count > 1);
+ EnableItem(IDX_COMPRESS_PREC_SET, setIsSupported);
+ ShowItem_Bool(IDX_COMPRESS_PREC_SET, setIsSupported);
+ }
+
+ SetTimeMAC();
+}
+
+
+void COptionsDialog::SetTimeMAC()
+{
+ const CArcInfoEx &ai = cd->Get_ArcInfoEx();
+
+ const
+ bool m_allow = ai.Flags_MTime();
+ bool c_allow = ai.Flags_CTime();
+ bool a_allow = ai.Flags_ATime();
+
+ if (ai.Is_Tar())
+ {
+ const int methodID = cd->GetMethodID();
+ c_allow = false;
+ a_allow = false;
+ if (methodID == kPosix)
+ {
+ // c_allow = true; // do we need it as change time ?
+ a_allow = true;
+ }
+ }
+
+ if (ai.Is_Zip())
+ {
+ // const int methodID = GetMethodID();
+ UInt32 prec = GetPrec();
+ if (prec == (UInt32)(Int32)-1)
+ prec = _auto_Prec;
+ if (prec != kTimePrec_Win)
+ {
+ c_allow = false;
+ a_allow = false;
+ }
+ }
+
+
+ /*
+ MTime.DefaultVal = true;
+ CTime.DefaultVal = false;
+ ATime.DefaultVal = false;
+ */
+
+ MTime.DefaultVal = ai.Flags_MTime_Default();
+ CTime.DefaultVal = ai.Flags_CTime_Default();
+ ATime.DefaultVal = ai.Flags_ATime_Default();
+
+ ZTime.DefaultVal = false;
+
+ const NCompression::CFormatOptions &fo = cd->Get_FormatOptions();
+
+ CheckButton_BoolBox (m_allow, fo.MTime, MTime );
+ CheckButton_BoolBox (c_allow, fo.CTime, CTime );
+ CheckButton_BoolBox (a_allow, fo.ATime, ATime );
+ CheckButton_BoolBox (true, fo.SetArcMTime, ZTime);
+
+ if (m_allow && !fo.MTime.Def)
+ {
+ const bool isSingleFile = ai.Flags_KeepName();
+ if (!isSingleFile)
+ {
+ // we can hide changing checkboxes for MTime here:
+ ShowItem_Bool (MTime.Set_Id, false);
+ EnableItem (MTime.Id, false);
+ }
+ }
+ // On_CheckBoxSet_Prec_Clicked();
+ // const bool isSingleFile = ai.Flags_KeepName();
+ // mtime for Gz can be
+}
+
+
+
+void COptionsDialog::On_CheckBoxSet_Prec_Clicked()
+{
+ const bool isSet = IsButtonCheckedBool(IDX_COMPRESS_PREC_SET);
+ if (!isSet)
+ {
+ // We save current MAC boxes to memory before SetPrec()
+ Store_TimeBoxes();
+ Reset_TimePrec();
+ SetPrec();
+ }
+ EnableItem(IDC_COMPRESS_TIME_PREC, isSet);
+}
+
+void COptionsDialog::On_CheckBoxSet_Clicked(const CBoolBox &bb)
+{
+ const bool isSet = IsButtonCheckedBool(bb.Set_Id);
+ if (!isSet)
+ CheckButton(bb.Id, bb.DefaultVal);
+ EnableItem(bb.Id, isSet);
+}
+
+
+
+
+#ifdef LANG
+static const UInt32 kLangIDs_Options[] =
+{
+ IDX_COMPRESS_NT_SYM_LINKS,
+ IDX_COMPRESS_NT_HARD_LINKS,
+ IDX_COMPRESS_NT_ALT_STREAMS,
+ IDX_COMPRESS_NT_SECUR,
+
+ IDG_COMPRESS_TIME,
+ IDT_COMPRESS_TIME_PREC,
+ IDX_COMPRESS_MTIME,
+ IDX_COMPRESS_CTIME,
+ IDX_COMPRESS_ATIME,
+ IDX_COMPRESS_ZTIME,
+ IDX_COMPRESS_PRESERVE_ATIME
+};
+#endif
+
+
+bool COptionsDialog::OnInit()
+{
+ #ifdef LANG
+ LangSetWindowText(*this, IDB_COMPRESS_OPTIONS); // IDS_OPTIONS
+ LangSetDlgItems(*this, kLangIDs_Options, ARRAY_SIZE(kLangIDs_Options));
+ // LangSetDlgItemText(*this, IDB_COMPRESS_TIME_DEFAULT, IDB_COMPRESS_TIME_DEFAULT);
+ // LangSetDlgItemText(*this, IDX_COMPRESS_TIME_DEFAULT, IDX_COMPRESS_TIME_DEFAULT);
+ #endif
+
+ LangString(IDS_COMPRESS_SEC, SecString);
+ if (SecString.IsEmpty())
+ SecString = "sec";
+ LangString(IDS_COMPRESS_NS, NsString);
+ if (NsString.IsEmpty())
+ NsString = "ns";
+
+ {
+ // const CArcInfoEx &ai = cd->Get_ArcInfoEx();
+
+ ShowItem_Bool ( IDX_COMPRESS_NT_SYM_LINKS, cd->SymLinks.Supported);
+ ShowItem_Bool ( IDX_COMPRESS_NT_HARD_LINKS, cd->HardLinks.Supported);
+ ShowItem_Bool ( IDX_COMPRESS_NT_ALT_STREAMS, cd->AltStreams.Supported);
+ ShowItem_Bool ( IDX_COMPRESS_NT_SECUR, cd->NtSecurity.Supported);
+
+ ShowItem_Bool ( IDG_COMPRESS_NTFS,
+ cd->SymLinks.Supported
+ || cd->HardLinks.Supported
+ || cd->AltStreams.Supported
+ || cd->NtSecurity.Supported);
+ }
+
+ /* we read property from two sources:
+ 1) command line : (Info)
+ 2) registry : (m_RegistryInfo)
+ (Info) has priority, if both are no defined */
+
+ CheckButton_Bool1 ( IDX_COMPRESS_NT_SYM_LINKS, cd->SymLinks);
+ CheckButton_Bool1 ( IDX_COMPRESS_NT_HARD_LINKS, cd->HardLinks);
+ CheckButton_Bool1 ( IDX_COMPRESS_NT_ALT_STREAMS, cd->AltStreams);
+ CheckButton_Bool1 ( IDX_COMPRESS_NT_SECUR, cd->NtSecurity);
+
+ CheckButton_Bool1 (IDX_COMPRESS_PRESERVE_ATIME, cd->PreserveATime);
+
+ m_Prec.Attach (GetItem(IDC_COMPRESS_TIME_PREC));
+
+ MTime.SetIDs ( IDX_COMPRESS_MTIME, IDX_COMPRESS_MTIME_SET);
+ CTime.SetIDs ( IDX_COMPRESS_CTIME, IDX_COMPRESS_CTIME_SET);
+ ATime.SetIDs ( IDX_COMPRESS_ATIME, IDX_COMPRESS_ATIME_SET);
+ ZTime.SetIDs ( IDX_COMPRESS_ZTIME, IDX_COMPRESS_ZTIME_SET);
+
+ {
+ const NCompression::CFormatOptions &fo = cd->Get_FormatOptions();
+ TimePrec = fo.TimePrec;
+ MTime.BoolPair = fo.MTime;
+ CTime.BoolPair = fo.CTime;
+ ATime.BoolPair = fo.ATime;
+ ZTime.BoolPair = fo.SetArcMTime;
+ }
+
+ SetPrec();
+
+ NormalizePosition();
+
+ return CModalDialog::OnInit();
+}
+
+
+bool COptionsDialog::OnCommand(int code, int itemID, LPARAM lParam)
+{
+ if (code == CBN_SELCHANGE)
+ {
+ switch (itemID)
+ {
+ case IDC_COMPRESS_TIME_PREC:
+ {
+ Store_TimeBoxes();
+ SetTimeMAC(); // for zip/tar
+ return true;
+ }
+ }
+ }
+ return CModalDialog::OnCommand(code, itemID, lParam);
+}
+
+
+bool COptionsDialog::OnButtonClicked(int buttonID, HWND buttonHWND)
+{
+ switch (buttonID)
+ {
+ case IDX_COMPRESS_PREC_SET: { On_CheckBoxSet_Prec_Clicked(); return true; }
+ case IDX_COMPRESS_MTIME_SET: { On_CheckBoxSet_Clicked (MTime); return true; }
+ case IDX_COMPRESS_CTIME_SET: { On_CheckBoxSet_Clicked (CTime); return true; }
+ case IDX_COMPRESS_ATIME_SET: { On_CheckBoxSet_Clicked (ATime); return true; }
+ case IDX_COMPRESS_ZTIME_SET: { On_CheckBoxSet_Clicked (ZTime); return true; }
+ }
+ return CModalDialog::OnButtonClicked(buttonID, buttonHWND);
+}
+
+
+void COptionsDialog::OnOK()
+{
+ GetButton_Bool1 (IDX_COMPRESS_NT_SYM_LINKS, cd->SymLinks);
+ GetButton_Bool1 (IDX_COMPRESS_NT_HARD_LINKS, cd->HardLinks);
+ GetButton_Bool1 (IDX_COMPRESS_NT_ALT_STREAMS, cd->AltStreams);
+ GetButton_Bool1 (IDX_COMPRESS_NT_SECUR, cd->NtSecurity);
+ GetButton_Bool1 (IDX_COMPRESS_PRESERVE_ATIME, cd->PreserveATime);
+
+ Store_TimeBoxes();
+ {
+ NCompression::CFormatOptions &fo = cd->Get_FormatOptions();
+ fo.TimePrec = TimePrec;
+ fo.MTime = MTime.BoolPair;
+ fo.CTime = CTime.BoolPair;
+ fo.ATime = ATime.BoolPair;
+ fo.SetArcMTime = ZTime.BoolPair;
+ }
+
+ CModalDialog::OnOK();
+}
+
+void COptionsDialog::OnHelp()
+{
+ ShowHelpWindow(kHelpTopic);
+}
diff --git a/CPP/7zip/UI/GUI/CompressDialog.h b/CPP/7zip/UI/GUI/CompressDialog.h
index 171d1189..d4590c9b 100644..100755
--- a/CPP/7zip/UI/GUI/CompressDialog.h
+++ b/CPP/7zip/UI/GUI/CompressDialog.h
@@ -59,6 +59,14 @@ namespace NCompressDialog
CBoolPair HardLinks;
CBoolPair AltStreams;
CBoolPair NtSecurity;
+
+ CBoolPair PreserveATime;
+
+ UInt32 TimePrec;
+ CBoolPair MTime;
+ CBoolPair CTime;
+ CBoolPair ATime;
+ CBoolPair SetArcMTime;
UString ArcPath; // in: Relative or abs ; out: Relative or abs
@@ -89,11 +97,46 @@ namespace NCompressDialog
Method.Empty();
Options.Empty();
EncryptionMethod.Empty();
+ TimePrec = (UInt32)(Int32)(-1);
}
};
}
+struct CBool1
+{
+ bool Val;
+ bool Supported;
+
+ CBool1(): Val(false), Supported(false) {}
+
+ void Init()
+ {
+ Val = false;
+ Supported = false;
+ }
+
+ void SetTrueTrue()
+ {
+ Val = true;
+ Supported = true;
+ }
+
+ void SetVal_as_Supported(bool val)
+ {
+ Val = val;
+ Supported = true;
+ }
+
+ /*
+ bool IsVal_True_and_Defined() const
+ {
+ return Def && Val;
+ }
+ */
+};
+
+
class CCompressDialog: public NWindows::NControl::CModalDialog
{
NWindows::NControl::CComboBox m_ArchivePath;
@@ -126,8 +169,6 @@ class CCompressDialog: public NWindows::NControl::CModalDialog
int _default_encryptionMethod_Index;
- NCompression::CInfo m_RegistryInfo;
-
int m_PrevFormat;
UString DirPrefix;
UString StartDirPrefix;
@@ -137,23 +178,25 @@ class CCompressDialog: public NWindows::NControl::CModalDialog
UInt64 _ramSize_Reduced; // full for 64-bit and reduced for 32-bit
UInt64 _ramUsage_Auto;
- void CheckButton_TwoBools(UINT id, const CBoolPair &b1, const CBoolPair &b2);
- void GetButton_Bools(UINT id, CBoolPair &b1, CBoolPair &b2);
+public:
+ NCompression::CInfo m_RegistryInfo;
+
+ CBool1 SymLinks;
+ CBool1 HardLinks;
+ CBool1 AltStreams;
+ CBool1 NtSecurity;
+ CBool1 PreserveATime;
void SetArchiveName(const UString &name);
int FindRegistryFormat(const UString &name);
- int FindRegistryFormatAlways(const UString &name);
+ unsigned FindRegistryFormat_Always(const UString &name);
const CArcInfoEx &Get_ArcInfoEx()
{
return (*ArcFormats)[GetFormatIndex()];
}
- NCompression::CFormatOptions &Get_FormatOptions()
- {
- const CArcInfoEx &ai = Get_ArcInfoEx();
- return m_RegistryInfo.Formats[ FindRegistryFormatAlways(ai.Name) ];
- }
+ NCompression::CFormatOptions &Get_FormatOptions();
void CheckSFXNameChange();
void SetArchiveName2(bool prevWasSFX);
@@ -237,6 +280,12 @@ class CCompressDialog: public NWindows::NControl::CModalDialog
UInt32 GetBlockSizeSpec() { return GetComboValue(m_Solid, 1); }
+ /*
+ UInt32 GetPrecSpec() { return GetComboValue(m_Prec, 1); }
+ UInt32 GetPrec() { return GetComboValue(m_Prec, 0); }
+ */
+
+
int AddOrder(UInt32 size);
int AddOrder_Auto();
@@ -271,6 +320,7 @@ class CCompressDialog: public NWindows::NControl::CModalDialog
void PrintMemUsage(UINT res, UInt64 value);
void SetMemoryUsage();
void SetParams();
+
void SaveOptionsInMem();
void UpdatePasswordControl();
@@ -283,7 +333,7 @@ class CCompressDialog: public NWindows::NControl::CModalDialog
void CheckSFXControlsEnable();
// void CheckVolumeEnable();
void EnableMultiCombo(unsigned id);
- void FormatChanged();
+ void FormatChanged(bool isChanged);
void OnButtonSetArchive();
bool IsSFX();
@@ -300,6 +350,8 @@ class CCompressDialog: public NWindows::NControl::CModalDialog
MessageBoxW(*this, message, L"7-Zip", MB_ICONERROR);
}
+ void ShowOptionsString();
+
public:
const CObjectVector<CArcInfoEx> *ArcFormats;
CUIntVector ArcIndices; // can not be empty, must contain Info.FormatIndex, if Info.FormatIndex >= 0
@@ -313,11 +365,103 @@ public:
INT_PTR Create(HWND wndParent = 0)
{
- BIG_DIALOG_SIZE(400, 304);
+ BIG_DIALOG_SIZE(400, 320);
return CModalDialog::Create(SIZED_DIALOG(IDD_COMPRESS), wndParent);
}
CCompressDialog(): CurrentDirWasChanged(false) {};
};
+
+
+
+class COptionsDialog: public NWindows::NControl::CModalDialog
+{
+ struct CBoolBox
+ {
+ bool IsSupported;
+ bool DefaultVal;
+ CBoolPair BoolPair;
+
+ int Id;
+ int Set_Id;
+
+ void SetIDs(int id, int set_Id)
+ {
+ Id = id;
+ Set_Id = set_Id;
+ }
+
+ CBoolBox():
+ IsSupported(false),
+ DefaultVal(false)
+ {}
+ };
+
+ CCompressDialog *cd;
+
+ NWindows::NControl::CComboBox m_Prec;
+
+ UInt32 _auto_Prec;
+ UInt32 TimePrec;
+
+ void Reset_TimePrec() { TimePrec = (UInt32)(Int32)-1; }
+ bool IsSet_TimePrec() const { return TimePrec != (UInt32)(Int32)-1; }
+
+ CBoolBox MTime;
+ CBoolBox CTime;
+ CBoolBox ATime;
+ CBoolBox ZTime;
+
+ UString SecString;
+ UString NsString;
+
+
+ void CheckButton_Bool1(UINT id, const CBool1 &b1);
+ void GetButton_Bool1(UINT id, CBool1 &b1);
+ void CheckButton_BoolBox(bool supported, const CBoolPair &b2, CBoolBox &bb);
+ void GetButton_BoolBox(CBoolBox &bb);
+
+ void Store_TimeBoxes();
+
+ UInt32 GetComboValue(NWindows::NControl::CComboBox &c, int defMax = 0);
+ UInt32 GetPrecSpec()
+ {
+ UInt32 prec = GetComboValue(m_Prec, 1);
+ if (prec == _auto_Prec)
+ prec = (UInt32)(Int32)-1;
+ return prec;
+ }
+ UInt32 GetPrec() { return GetComboValue(m_Prec, 0); }
+
+ // void OnButton_TimeDefault();
+ int AddPrec(unsigned prec, bool isDefault);
+ void SetPrec();
+ void SetTimeMAC();
+
+ void On_CheckBoxSet_Prec_Clicked();
+ void On_CheckBoxSet_Clicked(const CBoolBox &bb);
+
+ virtual bool OnInit();
+ virtual bool OnCommand(int code, int itemID, LPARAM lParam);
+ virtual bool OnButtonClicked(int buttonID, HWND buttonHWND);
+ virtual void OnOK();
+ virtual void OnHelp();
+
+public:
+
+ INT_PTR Create(HWND wndParent = 0)
+ {
+ BIG_DIALOG_SIZE(240, 232);
+ return CModalDialog::Create(SIZED_DIALOG(IDD_COMPRESS_OPTIONS), wndParent);
+ }
+
+ COptionsDialog(CCompressDialog *cdLoc):
+ cd(cdLoc)
+ // , TimePrec(0)
+ {
+ Reset_TimePrec();
+ };
+};
+
#endif
diff --git a/CPP/7zip/UI/GUI/CompressDialog.rc b/CPP/7zip/UI/GUI/CompressDialog.rc
index 52c9546a..d47a3edd 100644..100755
--- a/CPP/7zip/UI/GUI/CompressDialog.rc
+++ b/CPP/7zip/UI/GUI/CompressDialog.rc
@@ -2,7 +2,7 @@
#include "../../GuiCommon.rc"
#define xc 400
-#define yc 354
+#define yc 320
#undef gSize
#undef gSpace
@@ -20,10 +20,6 @@
#define gSize 192
#define gSpace 24
-#define ntSize2 168
-#define ntSizeX (ntSize2 - m - m)
-#define ntPosX m + m
-#define ntPosY 292
#define g1xs 88
#define g0xs (gSize - g1xs)
@@ -99,18 +95,9 @@ BEGIN
LTEXT "Parameters:", IDT_COMPRESS_PARAMETERS, m, 256, gSize, 8
EDITTEXT IDE_COMPRESS_PARAMETERS, m, 268, gSize, 14, ES_AUTOHSCROLL
-
- GROUPBOX "NTFS", IDG_COMPRESS_NTFS, m, ntPosY, ntSize2, 68
-
- CONTROL "Store symbolic links", IDX_COMPRESS_NT_SYM_LINKS, MY_CHECKBOX,
- ntPosX, ntPosY + 12, ntSizeX, 10
- CONTROL "Store hard links", IDX_COMPRESS_NT_HARD_LINKS, MY_CHECKBOX,
- ntPosX, ntPosY + 26, ntSizeX, 10
- CONTROL "Store alternate data streams", IDX_COMPRESS_NT_ALT_STREAMS, MY_CHECKBOX,
- ntPosX, ntPosY + 40, ntSizeX, 10
- CONTROL "Store file security", IDX_COMPRESS_NT_SECUR, MY_CHECKBOX,
- ntPosX, ntPosY + 54, ntSizeX, 10
-
+ PUSHBUTTON "Options", IDB_COMPRESS_OPTIONS, m, 292, bxs, bys
+ LTEXT "", IDT_COMPRESS_OPTIONS, m + bxs + m, 294, gSize - bxs - m, 16, SS_NOPREFIX
+
LTEXT "&Update mode:", IDT_COMPRESS_UPDATE_MODE, g4x, 41, 80, 8
COMBOBOX IDC_COMPRESS_UPDATE_MODE, g4x + 84, 39, g4xs - 84, 80, MY_COMBO
@@ -225,4 +212,10 @@ BEGIN
IDS_COMPRESS_SOLID "Solid"
IDS_SPLIT_CONFIRM "Specified volume size: {0} bytes.\nAre you sure you want to split archive into such volumes?"
+
+ IDS_COMPRESS_SEC "sec"
+ IDS_COMPRESS_NS "ns"
END
+
+
+#include "CompressOptionsDialog.rc"
diff --git a/CPP/7zip/UI/GUI/CompressDialogRes.h b/CPP/7zip/UI/GUI/CompressDialogRes.h
index 341b7533..80b39be5 100644..100755
--- a/CPP/7zip/UI/GUI/CompressDialogRes.h
+++ b/CPP/7zip/UI/GUI/CompressDialogRes.h
@@ -1,5 +1,6 @@
#define IDD_COMPRESS 4000
#define IDD_COMPRESS_2 14000
+#define IDD_COMPRESS_OPTIONS 14001
#define IDC_COMPRESS_ARCHIVE 100
#define IDB_COMPRESS_SET_ARCHIVE 101
@@ -28,6 +29,10 @@
#define IDT_COMPRESS_ARCHIVE_FOLDER 130
+// #define IDB_COMPRESS_OPTIONS 140
+#define IDB_COMPRESS_OPTIONS 2100
+#define IDT_COMPRESS_OPTIONS 141
+
#define IDT_COMPRESS_PATH_MODE 3410
#define IDT_PASSWORD_ENTER 3801
@@ -86,3 +91,31 @@
#define IDT_SPLIT_TO_VOLUMES 7302
#define IDS_INCORRECT_VOLUME_SIZE 7307
#define IDS_SPLIT_CONFIRM 7308
+
+
+// Options Dialog
+
+#define IDG_COMPRESS_TIME 4080
+#define IDT_COMPRESS_TIME_PREC 4081
+#define IDX_COMPRESS_MTIME 4082
+#define IDX_COMPRESS_CTIME 4083
+#define IDX_COMPRESS_ATIME 4084
+#define IDX_COMPRESS_ZTIME 4085
+#define IDX_COMPRESS_PRESERVE_ATIME 4086
+
+#define IDS_COMPRESS_SEC 4090
+#define IDS_COMPRESS_NS 4091
+
+#define IDC_COMPRESS_TIME_PREC 190
+#define IDT_COMPRESS_TIME_INFO 191
+
+#define IDX_COMPRESS_PREC_SET 201
+#define IDX_COMPRESS_MTIME_SET 202
+#define IDX_COMPRESS_CTIME_SET 203
+#define IDX_COMPRESS_ATIME_SET 204
+#define IDX_COMPRESS_ZTIME_SET 205
+
+// #define IDX_COMPRESS_NT_SYM_LINKS_SET 210
+// #define IDX_COMPRESS_NT_HARD_LINKS_SET 211
+// #define IDX_COMPRESS_NT_ALT_STREAMS_SET 212
+// #define IDX_COMPRESS_NT_SECUR_SET 213
diff --git a/CPP/7zip/UI/GUI/CompressOptionsDialog.rc b/CPP/7zip/UI/GUI/CompressOptionsDialog.rc
new file mode 100755
index 00000000..05782270
--- /dev/null
+++ b/CPP/7zip/UI/GUI/CompressOptionsDialog.rc
@@ -0,0 +1,76 @@
+#include "CompressDialogRes.h"
+#include "../../GuiCommon.rc"
+
+#define xc 240
+#define yc 232
+
+#define g5x m
+#define g5x2 (g5x + m)
+#define g5xs (xc)
+#define g5xs2 (g5xs - m - m)
+
+#define ntPosX g5x2
+#define ntPosY m
+#define ntSizeX g5xs2
+#define precSizeX 76
+
+#define ntSizeY 72
+#define timePosY (ntPosY + ntSizeY + 20)
+
+#define ceSize 18
+#define ceString ":"
+
+
+IDD_COMPRESS_OPTIONS DIALOG 0, 0, xs, ys MY_MODAL_DIALOG_STYLE MY_FONT
+CAPTION "Options"
+BEGIN
+ GROUPBOX "NTFS", IDG_COMPRESS_NTFS, g5x, ntPosY, g5xs, ntSizeY
+
+ CONTROL "Store symbolic links", IDX_COMPRESS_NT_SYM_LINKS, MY_CHECKBOX,
+ ntPosX, ntPosY + 12, ntSizeX, 10
+ CONTROL "Store hard links", IDX_COMPRESS_NT_HARD_LINKS, MY_CHECKBOX,
+ ntPosX, ntPosY + 26, ntSizeX, 10
+ CONTROL "Store alternate data streams", IDX_COMPRESS_NT_ALT_STREAMS, MY_CHECKBOX,
+ ntPosX, ntPosY + 40, ntSizeX, 10
+ CONTROL "Store file security", IDX_COMPRESS_NT_SECUR, MY_CHECKBOX,
+ ntPosX, ntPosY + 54, ntSizeX, 10
+
+ LTEXT "", IDT_COMPRESS_TIME_INFO, g5x, timePosY - 14, g5xs, 8
+
+
+ GROUPBOX "Time", IDG_COMPRESS_TIME, g5x, timePosY, g5xs, 112
+
+// CONTROL "Default", IDX_COMPRESS_TIME_DEFAULT, MY_CHECKBOX,
+// ntPosX, timePosY + 10, ntSizeX, 16
+
+ CONTROL ceString, IDX_COMPRESS_PREC_SET, MY_CHECKBOX, ntPosX, timePosY + 14, ceSize, 10
+ LTEXT "Timestamp precision:", IDT_COMPRESS_TIME_PREC,
+ ntPosX + ceSize, timePosY + 14, ntSizeX - precSizeX - ceSize, 8
+ COMBOBOX IDC_COMPRESS_TIME_PREC, ntPosX + ntSizeX - precSizeX, timePosY + 12, precSizeX, 70, MY_COMBO
+
+ // PUSHBUTTON "Default", IDB_COMPRESS_TIME_DEFAULT, ntPosX + ntSizeX - bxs, timePosY + 22, bxs, bys, WS_GROUP
+
+ CONTROL ceString, IDX_COMPRESS_MTIME_SET, MY_CHECKBOX, ntPosX, timePosY + 28, ceSize, 10
+ CONTROL "Store modification time", IDX_COMPRESS_MTIME, MY_CHECKBOX,
+ ntPosX + ceSize, timePosY + 28, ntSizeX - ceSize, 10
+
+ CONTROL ceString, IDX_COMPRESS_CTIME_SET, MY_CHECKBOX, ntPosX, timePosY + 42, ceSize, 10
+ CONTROL "Store creation time", IDX_COMPRESS_CTIME, MY_CHECKBOX,
+ ntPosX + ceSize, timePosY + 42, ntSizeX - ceSize, 10
+
+ CONTROL ceString, IDX_COMPRESS_ATIME_SET, MY_CHECKBOX, ntPosX, timePosY + 56, ceSize, 10
+ CONTROL "Store last access time", IDX_COMPRESS_ATIME, MY_CHECKBOX,
+ ntPosX + ceSize, timePosY + 56, ntSizeX - ceSize, 10
+
+ CONTROL ceString, IDX_COMPRESS_ZTIME_SET, MY_CHECKBOX | BS_MULTILINE, ntPosX, timePosY + 72, ceSize, 16
+ CONTROL "Set archive time to latest file time", IDX_COMPRESS_ZTIME, MY_CHECKBOX | BS_MULTILINE,
+ ntPosX + ceSize, timePosY + 72, ntSizeX - ceSize, 16
+
+ CONTROL "Do not change source files last access time", IDX_COMPRESS_PRESERVE_ATIME, MY_CHECKBOX | BS_MULTILINE,
+ ntPosX, timePosY + 92, ntSizeX, 16
+
+
+ DEFPUSHBUTTON "OK", IDOK, bx3, by, bxs, bys, WS_GROUP
+ PUSHBUTTON "Cancel", IDCANCEL, bx2, by, bxs, bys
+ PUSHBUTTON "Help", IDHELP, bx1, by, bxs, bys
+END
diff --git a/CPP/7zip/UI/GUI/Extract.rc b/CPP/7zip/UI/GUI/Extract.rc
index 36bfb009..36bfb009 100644..100755
--- a/CPP/7zip/UI/GUI/Extract.rc
+++ b/CPP/7zip/UI/GUI/Extract.rc
diff --git a/CPP/7zip/UI/GUI/ExtractDialog.cpp b/CPP/7zip/UI/GUI/ExtractDialog.cpp
index 5132084d..5132084d 100644..100755
--- a/CPP/7zip/UI/GUI/ExtractDialog.cpp
+++ b/CPP/7zip/UI/GUI/ExtractDialog.cpp
diff --git a/CPP/7zip/UI/GUI/ExtractDialog.h b/CPP/7zip/UI/GUI/ExtractDialog.h
index 33349ffc..33349ffc 100644..100755
--- a/CPP/7zip/UI/GUI/ExtractDialog.h
+++ b/CPP/7zip/UI/GUI/ExtractDialog.h
diff --git a/CPP/7zip/UI/GUI/ExtractDialog.rc b/CPP/7zip/UI/GUI/ExtractDialog.rc
index 3728b96d..3728b96d 100644..100755
--- a/CPP/7zip/UI/GUI/ExtractDialog.rc
+++ b/CPP/7zip/UI/GUI/ExtractDialog.rc
diff --git a/CPP/7zip/UI/GUI/ExtractDialogRes.h b/CPP/7zip/UI/GUI/ExtractDialogRes.h
index ed12bfb3..ed12bfb3 100644..100755
--- a/CPP/7zip/UI/GUI/ExtractDialogRes.h
+++ b/CPP/7zip/UI/GUI/ExtractDialogRes.h
diff --git a/CPP/7zip/UI/GUI/ExtractGUI.cpp b/CPP/7zip/UI/GUI/ExtractGUI.cpp
index a9191a8b..a9191a8b 100644..100755
--- a/CPP/7zip/UI/GUI/ExtractGUI.cpp
+++ b/CPP/7zip/UI/GUI/ExtractGUI.cpp
diff --git a/CPP/7zip/UI/GUI/ExtractGUI.h b/CPP/7zip/UI/GUI/ExtractGUI.h
index 3b412590..3b412590 100644..100755
--- a/CPP/7zip/UI/GUI/ExtractGUI.h
+++ b/CPP/7zip/UI/GUI/ExtractGUI.h
diff --git a/CPP/7zip/UI/GUI/ExtractRes.h b/CPP/7zip/UI/GUI/ExtractRes.h
index 634ba6b5..634ba6b5 100644..100755
--- a/CPP/7zip/UI/GUI/ExtractRes.h
+++ b/CPP/7zip/UI/GUI/ExtractRes.h
diff --git a/CPP/7zip/UI/GUI/FM.ico b/CPP/7zip/UI/GUI/FM.ico
index 3a0a34da..3a0a34da 100644..100755
--- a/CPP/7zip/UI/GUI/FM.ico
+++ b/CPP/7zip/UI/GUI/FM.ico
Binary files differ
diff --git a/CPP/7zip/UI/GUI/GUI.cpp b/CPP/7zip/UI/GUI/GUI.cpp
index 32a48e74..c977516c 100644..100755
--- a/CPP/7zip/UI/GUI/GUI.cpp
+++ b/CPP/7zip/UI/GUI/GUI.cpp
@@ -75,6 +75,8 @@ extern
bool g_LVN_ITEMACTIVATE_Support;
bool g_LVN_ITEMACTIVATE_Support = true;
+DECLARE_AND_SET_CLIENT_VERSION_VAR
+
static void ErrorMessage(LPCWSTR message)
{
MessageBoxW(NULL, message, L"7-Zip", MB_ICONERROR | MB_OK);
@@ -135,7 +137,7 @@ static 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);
diff --git a/CPP/7zip/UI/GUI/GUI.dsp b/CPP/7zip/UI/GUI/GUI.dsp
index 53a2c92f..b55a115c 100644..100755
--- a/CPP/7zip/UI/GUI/GUI.dsp
+++ b/CPP/7zip/UI/GUI/GUI.dsp
@@ -773,6 +773,10 @@ SOURCE=..\..\..\..\C\7zCrcOpt.c
# End Source File
# Begin Source File
+SOURCE=..\..\..\..\C\7zTypes.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\..\..\C\Alloc.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
@@ -1211,5 +1215,17 @@ SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp
SOURCE=..\..\Archive\Common\OutStreamWithCRC.h
# End Source File
# End Group
+# Begin Group "7-Zip"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\IArchive.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\ICoder.h
+# End Source File
+# End Group
# End Target
# End Project
diff --git a/CPP/7zip/UI/GUI/GUI.dsw b/CPP/7zip/UI/GUI/GUI.dsw
index 85d33484..85d33484 100644..100755
--- a/CPP/7zip/UI/GUI/GUI.dsw
+++ b/CPP/7zip/UI/GUI/GUI.dsw
diff --git a/CPP/7zip/UI/GUI/HashGUI.cpp b/CPP/7zip/UI/GUI/HashGUI.cpp
index 5782f790..5782f790 100644..100755
--- a/CPP/7zip/UI/GUI/HashGUI.cpp
+++ b/CPP/7zip/UI/GUI/HashGUI.cpp
diff --git a/CPP/7zip/UI/GUI/HashGUI.h b/CPP/7zip/UI/GUI/HashGUI.h
index 82644535..82644535 100644..100755
--- a/CPP/7zip/UI/GUI/HashGUI.h
+++ b/CPP/7zip/UI/GUI/HashGUI.h
diff --git a/CPP/7zip/UI/GUI/StdAfx.cpp b/CPP/7zip/UI/GUI/StdAfx.cpp
index d0feea85..d0feea85 100644..100755
--- a/CPP/7zip/UI/GUI/StdAfx.cpp
+++ b/CPP/7zip/UI/GUI/StdAfx.cpp
diff --git a/CPP/7zip/UI/GUI/StdAfx.h b/CPP/7zip/UI/GUI/StdAfx.h
index 1918c8c4..1918c8c4 100644..100755
--- a/CPP/7zip/UI/GUI/StdAfx.h
+++ b/CPP/7zip/UI/GUI/StdAfx.h
diff --git a/CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp b/CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp
index 1f272cd9..1f272cd9 100644..100755
--- a/CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp
+++ b/CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp
diff --git a/CPP/7zip/UI/GUI/UpdateCallbackGUI.h b/CPP/7zip/UI/GUI/UpdateCallbackGUI.h
index 2e0c111b..2e0c111b 100644..100755
--- a/CPP/7zip/UI/GUI/UpdateCallbackGUI.h
+++ b/CPP/7zip/UI/GUI/UpdateCallbackGUI.h
diff --git a/CPP/7zip/UI/GUI/UpdateCallbackGUI2.cpp b/CPP/7zip/UI/GUI/UpdateCallbackGUI2.cpp
index 4eeead7d..4eeead7d 100644..100755
--- a/CPP/7zip/UI/GUI/UpdateCallbackGUI2.cpp
+++ b/CPP/7zip/UI/GUI/UpdateCallbackGUI2.cpp
diff --git a/CPP/7zip/UI/GUI/UpdateCallbackGUI2.h b/CPP/7zip/UI/GUI/UpdateCallbackGUI2.h
index 2b30ad21..2b30ad21 100644..100755
--- a/CPP/7zip/UI/GUI/UpdateCallbackGUI2.h
+++ b/CPP/7zip/UI/GUI/UpdateCallbackGUI2.h
diff --git a/CPP/7zip/UI/GUI/UpdateGUI.cpp b/CPP/7zip/UI/GUI/UpdateGUI.cpp
index a3a1d889..2d041437 100644..100755
--- a/CPP/7zip/UI/GUI/UpdateGUI.cpp
+++ b/CPP/7zip/UI/GUI/UpdateGUI.cpp
@@ -61,6 +61,53 @@ HRESULT CThreadUpdating::ProcessVirt()
return HRESULT_FROM_WIN32(ei.SystemError);
}
+
+// parse command line properties
+
+static bool ParseProp_Time_BoolPair(const CProperty &prop, const char *name, CBoolPair &bp)
+{
+ if (!prop.Name.IsPrefixedBy_Ascii_NoCase(name))
+ return false;
+ const UString rem = prop.Name.Ptr((unsigned)strlen(name));
+ UString val = prop.Value;
+ if (!rem.IsEmpty())
+ {
+ if (!val.IsEmpty())
+ return true;
+ val = rem;
+ }
+ bool res;
+ if (StringToBool(val, res))
+ {
+ bp.Val = res;
+ bp.Def = true;
+ }
+ return true;
+}
+
+static void ParseProp(
+ const CProperty &prop,
+ NCompressDialog::CInfo &di)
+{
+ if (ParseProp_Time_BoolPair(prop, "tm", di.MTime)) return;
+ if (ParseProp_Time_BoolPair(prop, "tc", di.CTime)) return;
+ if (ParseProp_Time_BoolPair(prop, "ta", di.ATime)) return;
+}
+
+static void ParseProperties(
+ const CObjectVector<CProperty> &properties,
+ NCompressDialog::CInfo &di)
+{
+ FOR_VECTOR (i, properties)
+ {
+ ParseProp(properties[i], di);
+ }
+}
+
+
+
+
+
static void AddProp_UString(CObjectVector<CProperty> &properties, const char *name, const UString &value)
{
CProperty prop;
@@ -81,10 +128,31 @@ static void AddProp_bool(CObjectVector<CProperty> &properties, const char *name,
AddProp_UString(properties, name, UString(value ? "on": "off"));
}
-static bool IsThereMethodOverride(bool is7z, const UString &propertiesString)
+
+static void AddProp_BoolPair(CObjectVector<CProperty> &properties,
+ const char *name, const CBoolPair &bp)
+{
+ if (bp.Def)
+ AddProp_bool(properties, name, bp.Val);
+}
+
+
+
+static void SplitOptionsToStrings(const UString &src, UStringVector &strings)
+{
+ SplitString(src, strings);
+ FOR_VECTOR (i, strings)
+ {
+ UString &s = strings[i];
+ if (s.Len() > 2
+ && s[0] == '-'
+ && MyCharLower_Ascii(s[1]) == 'm')
+ s.DeleteFrontal(2);
+ }
+}
+
+static bool IsThereMethodOverride(bool is7z, const UStringVector &strings)
{
- UStringVector strings;
- SplitString(propertiesString, strings);
FOR_VECTOR (i, strings)
{
const UString &s = strings[i];
@@ -106,17 +174,11 @@ static bool IsThereMethodOverride(bool is7z, const UString &propertiesString)
}
static void ParseAndAddPropertires(CObjectVector<CProperty> &properties,
- const UString &propertiesString)
+ const UStringVector &strings)
{
- UStringVector strings;
- SplitString(propertiesString, strings);
FOR_VECTOR (i, strings)
{
- UString s = strings[i];
- if (s.Len() > 2
- && s[0] == '-'
- && MyCharLower_Ascii(s[1]) == 'm')
- s.DeleteFrontal(2);
+ const UString &s = strings[i];
CProperty property;
const int index = s.Find(L'=');
if (index < 0)
@@ -142,58 +204,49 @@ static void AddProp_Size(CObjectVector<CProperty> &properties, const char *name,
static void SetOutProperties(
CObjectVector<CProperty> &properties,
+ const NCompressDialog::CInfo &di,
bool is7z,
- UInt32 level,
- bool setMethod,
- const UString &method,
- UInt64 dict64,
- bool orderMode,
- UInt32 order,
- bool solidIsSpecified, UInt64 solidBlockSize,
- // bool multiThreadIsAllowed,
- UInt32 numThreads,
- const UString &encryptionMethod,
- bool encryptHeadersIsAllowed, bool encryptHeaders,
- const NCompression::CMemUse &memUse,
- bool /* sfxMode */)
+ bool setMethod)
{
- if (level != (UInt32)(Int32)-1)
- AddProp_UInt32(properties, "x", (UInt32)level);
+ if (di.Level != (UInt32)(Int32)-1)
+ AddProp_UInt32(properties, "x", (UInt32)di.Level);
if (setMethod)
{
- if (!method.IsEmpty())
- AddProp_UString(properties, is7z ? "0": "m", method);
- if (dict64 != (UInt64)(Int64)-1)
+ if (!di.Method.IsEmpty())
+ AddProp_UString(properties, is7z ? "0": "m", di.Method);
+ if (di.Dict64 != (UInt64)(Int64)-1)
{
AString name;
if (is7z)
name = "0";
- name += (orderMode ? "mem" : "d");
- AddProp_Size(properties, name, dict64);
+ name += (di.OrderMode ? "mem" : "d");
+ AddProp_Size(properties, name, di.Dict64);
}
- if (order != (UInt32)(Int32)-1)
+ if (di.Order != (UInt32)(Int32)-1)
{
AString name;
if (is7z)
name = "0";
- name += (orderMode ? "o" : "fb");
- AddProp_UInt32(properties, name, (UInt32)order);
+ name += (di.OrderMode ? "o" : "fb");
+ AddProp_UInt32(properties, name, (UInt32)di.Order);
}
}
- if (!encryptionMethod.IsEmpty())
- AddProp_UString(properties, "em", encryptionMethod);
+ if (!di.EncryptionMethod.IsEmpty())
+ AddProp_UString(properties, "em", di.EncryptionMethod);
- if (encryptHeadersIsAllowed)
- AddProp_bool(properties, "he", encryptHeaders);
- if (solidIsSpecified)
- AddProp_Size(properties, "s", solidBlockSize);
+ if (di.EncryptHeadersIsAllowed)
+ AddProp_bool(properties, "he", di.EncryptHeaders);
+
+ if (di.SolidIsSpecified)
+ AddProp_Size(properties, "s", di.SolidBlockSize);
if (
- // multiThreadIsAllowed &&
- numThreads != (UInt32)(Int32)-1)
- AddProp_UInt32(properties, "mt", numThreads);
+ // di.MultiThreadIsAllowed &&
+ di.NumThreads != (UInt32)(Int32)-1)
+ AddProp_UInt32(properties, "mt", di.NumThreads);
+ const NCompression::CMemUse &memUse = di.MemUsage;
if (memUse.IsDefined)
{
const char *kMemUse = "memuse";
@@ -208,8 +261,16 @@ static void SetOutProperties(
else
AddProp_Size(properties, kMemUse, memUse.Val);
}
+
+ AddProp_BoolPair(properties, "tm", di.MTime);
+ AddProp_BoolPair(properties, "tc", di.CTime);
+ AddProp_BoolPair(properties, "ta", di.ATime);
+
+ if (di.TimePrec != (UInt32)(Int32)-1)
+ AddProp_UInt32(properties, "tp", di.TimePrec);
}
+
struct C_UpdateMode_ToAction_Pair
{
NCompressDialog::NUpdateMode::EEnum UpdateMode;
@@ -358,6 +419,10 @@ static HRESULT ShowDialog(
di.HardLinks = options.HardLinks;
di.AltStreams = options.AltStreams;
di.NtSecurity = options.NtSecurity;
+ if (options.SetArcMTime)
+ di.SetArcMTime.SetTrueTrue();
+ if (options.PreserveATime)
+ di.PreserveATime.SetTrueTrue();
if (callback->PasswordIsDefined)
di.Password = callback->Password;
@@ -373,6 +438,8 @@ static HRESULT ShowDialog(
di.UpdateMode = g_UpdateMode_Pairs[(unsigned)index].UpdateMode;
}
+ ParseProperties(options.MethodMode.Properties, di);
+
if (dialog.Create(hwndParent) != IDOK)
return E_ABORT;
@@ -382,6 +449,9 @@ static HRESULT ShowDialog(
options.HardLinks = di.HardLinks;
options.AltStreams = di.AltStreams;
options.NtSecurity = di.NtSecurity;
+ options.SetArcMTime = di.SetArcMTime.Val;
+ if (di.PreserveATime.Def)
+ options.PreserveATime = di.PreserveATime.Val;
#if defined(_WIN32) && !defined(UNDER_CE)
curDirRestorer.NeedRestore = dialog.CurrentDirWasChanged;
@@ -411,29 +481,21 @@ static HRESULT ShowDialog(
if (callback->PasswordIsDefined)
callback->Password = di.Password;
+ // we clear command line options, and fill options form Dialog
options.MethodMode.Properties.Clear();
- bool is7z = archiverInfo.Name.IsEqualTo_Ascii_NoCase("7z");
- bool methodOverride = IsThereMethodOverride(is7z, di.Options);
+ const bool is7z = archiverInfo.Is_7z();
+
+ UStringVector optionStrings;
+ SplitOptionsToStrings(di.Options, optionStrings);
+ const bool methodOverride = IsThereMethodOverride(is7z, optionStrings);
- SetOutProperties(
- options.MethodMode.Properties,
+ SetOutProperties(options.MethodMode.Properties, di,
is7z,
- di.Level,
- !methodOverride,
- di.Method,
- di.Dict64,
- di.OrderMode, di.Order,
- di.SolidIsSpecified, di.SolidBlockSize,
- // di.MultiThreadIsAllowed,
- di.NumThreads,
- di.EncryptionMethod,
- di.EncryptHeadersIsAllowed, di.EncryptHeaders,
- di.MemUsage,
- di.SFXMode);
+ !methodOverride); // setMethod
options.OpenShareForWrite = di.OpenShareForWrite;
- ParseAndAddPropertires(options.MethodMode.Properties, di.Options);
+ ParseAndAddPropertires(options.MethodMode.Properties, optionStrings);
if (di.SFXMode)
options.SfxMode = true;
diff --git a/CPP/7zip/UI/GUI/UpdateGUI.h b/CPP/7zip/UI/GUI/UpdateGUI.h
index d1880de0..d1880de0 100644..100755
--- a/CPP/7zip/UI/GUI/UpdateGUI.h
+++ b/CPP/7zip/UI/GUI/UpdateGUI.h
diff --git a/CPP/7zip/UI/GUI/makefile b/CPP/7zip/UI/GUI/makefile
index 123410c1..123410c1 100644..100755
--- a/CPP/7zip/UI/GUI/makefile
+++ b/CPP/7zip/UI/GUI/makefile
diff --git a/CPP/7zip/UI/GUI/resource.rc b/CPP/7zip/UI/GUI/resource.rc
index 04af8157..04af8157 100644..100755
--- a/CPP/7zip/UI/GUI/resource.rc
+++ b/CPP/7zip/UI/GUI/resource.rc
diff --git a/CPP/7zip/UI/GUI/resource2.h b/CPP/7zip/UI/GUI/resource2.h
index cd882924..cd882924 100644..100755
--- a/CPP/7zip/UI/GUI/resource2.h
+++ b/CPP/7zip/UI/GUI/resource2.h
diff --git a/CPP/7zip/UI/GUI/resource2.rc b/CPP/7zip/UI/GUI/resource2.rc
index 49534f50..49534f50 100644..100755
--- a/CPP/7zip/UI/GUI/resource2.rc
+++ b/CPP/7zip/UI/GUI/resource2.rc
diff --git a/CPP/7zip/UI/GUI/resource3.h b/CPP/7zip/UI/GUI/resource3.h
index c25737fa..c25737fa 100644..100755
--- a/CPP/7zip/UI/GUI/resource3.h
+++ b/CPP/7zip/UI/GUI/resource3.h
diff --git a/CPP/7zip/UI/GUI/resource3.rc b/CPP/7zip/UI/GUI/resource3.rc
index cfc8bc35..cfc8bc35 100644..100755
--- a/CPP/7zip/UI/GUI/resource3.rc
+++ b/CPP/7zip/UI/GUI/resource3.rc
diff --git a/CPP/7zip/UI/makefile b/CPP/7zip/UI/makefile
index 1b0cdbe1..1b0cdbe1 100644..100755
--- a/CPP/7zip/UI/makefile
+++ b/CPP/7zip/UI/makefile
diff --git a/CPP/7zip/cmpl_clang.mak b/CPP/7zip/cmpl_clang.mak
index e62e1e62..e62e1e62 100644..100755
--- a/CPP/7zip/cmpl_clang.mak
+++ b/CPP/7zip/cmpl_clang.mak
diff --git a/CPP/7zip/cmpl_clang_arm64.mak b/CPP/7zip/cmpl_clang_arm64.mak
index 3f6b02bf..3f6b02bf 100644..100755
--- a/CPP/7zip/cmpl_clang_arm64.mak
+++ b/CPP/7zip/cmpl_clang_arm64.mak
diff --git a/CPP/7zip/cmpl_clang_x64.mak b/CPP/7zip/cmpl_clang_x64.mak
index b61e2af6..b61e2af6 100644..100755
--- a/CPP/7zip/cmpl_clang_x64.mak
+++ b/CPP/7zip/cmpl_clang_x64.mak
diff --git a/CPP/7zip/cmpl_clang_x86.mak b/CPP/7zip/cmpl_clang_x86.mak
index 0e5cb76c..0e5cb76c 100644..100755
--- a/CPP/7zip/cmpl_clang_x86.mak
+++ b/CPP/7zip/cmpl_clang_x86.mak
diff --git a/CPP/7zip/cmpl_gcc.mak b/CPP/7zip/cmpl_gcc.mak
index 7a1aef2e..7a1aef2e 100644..100755
--- a/CPP/7zip/cmpl_gcc.mak
+++ b/CPP/7zip/cmpl_gcc.mak
diff --git a/CPP/7zip/cmpl_gcc_arm64.mak b/CPP/7zip/cmpl_gcc_arm64.mak
index 53a85844..53a85844 100644..100755
--- a/CPP/7zip/cmpl_gcc_arm64.mak
+++ b/CPP/7zip/cmpl_gcc_arm64.mak
diff --git a/CPP/7zip/cmpl_gcc_x64.mak b/CPP/7zip/cmpl_gcc_x64.mak
index 500c30e4..500c30e4 100644..100755
--- a/CPP/7zip/cmpl_gcc_x64.mak
+++ b/CPP/7zip/cmpl_gcc_x64.mak
diff --git a/CPP/7zip/cmpl_gcc_x86.mak b/CPP/7zip/cmpl_gcc_x86.mak
index e7687070..e7687070 100644..100755
--- a/CPP/7zip/cmpl_gcc_x86.mak
+++ b/CPP/7zip/cmpl_gcc_x86.mak
diff --git a/CPP/7zip/cmpl_mac_arm64.mak b/CPP/7zip/cmpl_mac_arm64.mak
index 941028e9..941028e9 100644..100755
--- a/CPP/7zip/cmpl_mac_arm64.mak
+++ b/CPP/7zip/cmpl_mac_arm64.mak
diff --git a/CPP/7zip/cmpl_mac_x64.mak b/CPP/7zip/cmpl_mac_x64.mak
index d3aa0396..d3aa0396 100644..100755
--- a/CPP/7zip/cmpl_mac_x64.mak
+++ b/CPP/7zip/cmpl_mac_x64.mak
diff --git a/CPP/7zip/makefile b/CPP/7zip/makefile
index 9d31e6bd..9d31e6bd 100644..100755
--- a/CPP/7zip/makefile
+++ b/CPP/7zip/makefile
diff --git a/CPP/7zip/var_clang.mak b/CPP/7zip/var_clang.mak
index a6df26e7..a6df26e7 100644..100755
--- a/CPP/7zip/var_clang.mak
+++ b/CPP/7zip/var_clang.mak
diff --git a/CPP/7zip/var_clang_arm64.mak b/CPP/7zip/var_clang_arm64.mak
index 4b354096..4b354096 100644..100755
--- a/CPP/7zip/var_clang_arm64.mak
+++ b/CPP/7zip/var_clang_arm64.mak
diff --git a/CPP/7zip/var_clang_x64.mak b/CPP/7zip/var_clang_x64.mak
index fefed51c..fefed51c 100644..100755
--- a/CPP/7zip/var_clang_x64.mak
+++ b/CPP/7zip/var_clang_x64.mak
diff --git a/CPP/7zip/var_clang_x86.mak b/CPP/7zip/var_clang_x86.mak
index 5f3c2d9c..5f3c2d9c 100644..100755
--- a/CPP/7zip/var_clang_x86.mak
+++ b/CPP/7zip/var_clang_x86.mak
diff --git a/CPP/7zip/var_gcc.mak b/CPP/7zip/var_gcc.mak
index 664491cf..664491cf 100644..100755
--- a/CPP/7zip/var_gcc.mak
+++ b/CPP/7zip/var_gcc.mak
diff --git a/CPP/7zip/var_gcc_arm64.mak b/CPP/7zip/var_gcc_arm64.mak
index 4bbb687d..4bbb687d 100644..100755
--- a/CPP/7zip/var_gcc_arm64.mak
+++ b/CPP/7zip/var_gcc_arm64.mak
diff --git a/CPP/7zip/var_gcc_x64.mak b/CPP/7zip/var_gcc_x64.mak
index 1acf604f..1acf604f 100644..100755
--- a/CPP/7zip/var_gcc_x64.mak
+++ b/CPP/7zip/var_gcc_x64.mak
diff --git a/CPP/7zip/var_gcc_x86.mak b/CPP/7zip/var_gcc_x86.mak
index 288bf94b..288bf94b 100644..100755
--- a/CPP/7zip/var_gcc_x86.mak
+++ b/CPP/7zip/var_gcc_x86.mak
diff --git a/CPP/7zip/var_mac_arm64.mak b/CPP/7zip/var_mac_arm64.mak
index adf5fa1d..adf5fa1d 100644..100755
--- a/CPP/7zip/var_mac_arm64.mak
+++ b/CPP/7zip/var_mac_arm64.mak
diff --git a/CPP/7zip/var_mac_x64.mak b/CPP/7zip/var_mac_x64.mak
index 13d7aa7f..13d7aa7f 100644..100755
--- a/CPP/7zip/var_mac_x64.mak
+++ b/CPP/7zip/var_mac_x64.mak
diff --git a/CPP/7zip/warn_clang.mak b/CPP/7zip/warn_clang.mak
index ed4f908f..ed4f908f 100644..100755
--- a/CPP/7zip/warn_clang.mak
+++ b/CPP/7zip/warn_clang.mak
diff --git a/CPP/7zip/warn_clang_mac.mak b/CPP/7zip/warn_clang_mac.mak
index aadf14f7..aadf14f7 100644..100755
--- a/CPP/7zip/warn_clang_mac.mak
+++ b/CPP/7zip/warn_clang_mac.mak
diff --git a/CPP/7zip/warn_gcc.mak b/CPP/7zip/warn_gcc.mak
index 3185326a..3185326a 100644..100755
--- a/CPP/7zip/warn_gcc.mak
+++ b/CPP/7zip/warn_gcc.mak
diff --git a/CPP/Build.mak b/CPP/Build.mak
index 1ef676e0..1ef676e0 100644..100755
--- a/CPP/Build.mak
+++ b/CPP/Build.mak
diff --git a/CPP/Common/AutoPtr.h b/CPP/Common/AutoPtr.h
index 006d3155..006d3155 100644..100755
--- a/CPP/Common/AutoPtr.h
+++ b/CPP/Common/AutoPtr.h
diff --git a/CPP/Common/CRC.cpp b/CPP/Common/CRC.cpp
index c6b7d5e4..c6b7d5e4 100644..100755
--- a/CPP/Common/CRC.cpp
+++ b/CPP/Common/CRC.cpp
diff --git a/CPP/Common/C_FileIO.cpp b/CPP/Common/C_FileIO.cpp
index 4bd3fadc..4bd3fadc 100644..100755
--- a/CPP/Common/C_FileIO.cpp
+++ b/CPP/Common/C_FileIO.cpp
diff --git a/CPP/Common/C_FileIO.h b/CPP/Common/C_FileIO.h
index 6818558b..6818558b 100644..100755
--- a/CPP/Common/C_FileIO.h
+++ b/CPP/Common/C_FileIO.h
diff --git a/CPP/Common/CksumReg.cpp b/CPP/Common/CksumReg.cpp
index 29d9f82e..29d9f82e 100644..100755
--- a/CPP/Common/CksumReg.cpp
+++ b/CPP/Common/CksumReg.cpp
diff --git a/CPP/Common/ComTry.h b/CPP/Common/ComTry.h
index 297c407b..297c407b 100644..100755
--- a/CPP/Common/ComTry.h
+++ b/CPP/Common/ComTry.h
diff --git a/CPP/Common/CommandLineParser.cpp b/CPP/Common/CommandLineParser.cpp
index 465e0fde..465e0fde 100644..100755
--- a/CPP/Common/CommandLineParser.cpp
+++ b/CPP/Common/CommandLineParser.cpp
diff --git a/CPP/Common/CommandLineParser.h b/CPP/Common/CommandLineParser.h
index fbd4fa58..fbd4fa58 100644..100755
--- a/CPP/Common/CommandLineParser.h
+++ b/CPP/Common/CommandLineParser.h
diff --git a/CPP/Common/Common.h b/CPP/Common/Common.h
index 8dac613c..72db7a8b 100644..100755
--- a/CPP/Common/Common.h
+++ b/CPP/Common/Common.h
@@ -35,7 +35,7 @@ you can change this h file or h files included in this file.
So we can use MY_ARRAY_NEW macro instead of new[] operator. */
#if defined(_MSC_VER) && (_MSC_VER == 1200) && !defined(_WIN64)
- #define MY_ARRAY_NEW(p, T, size) p = new T[(size > (unsigned)0xFFFFFFFF / sizeof(T)) ? (unsigned)0xFFFFFFFF / sizeof(T) : size];
+ #define MY_ARRAY_NEW(p, T, size) p = new T[((size) > (unsigned)0xFFFFFFFF / sizeof(T)) ? (unsigned)0xFFFFFFFF / sizeof(T) : (size)];
#else
#define MY_ARRAY_NEW(p, T, size) p = new T[size];
#endif
diff --git a/CPP/Common/CrcReg.cpp b/CPP/Common/CrcReg.cpp
index fdbba77b..fdbba77b 100644..100755
--- a/CPP/Common/CrcReg.cpp
+++ b/CPP/Common/CrcReg.cpp
diff --git a/CPP/Common/Defs.h b/CPP/Common/Defs.h
index 9adb88cf..9adb88cf 100644..100755
--- a/CPP/Common/Defs.h
+++ b/CPP/Common/Defs.h
diff --git a/CPP/Common/DynLimBuf.cpp b/CPP/Common/DynLimBuf.cpp
index 79141040..79141040 100644..100755
--- a/CPP/Common/DynLimBuf.cpp
+++ b/CPP/Common/DynLimBuf.cpp
diff --git a/CPP/Common/DynLimBuf.h b/CPP/Common/DynLimBuf.h
index e80a7e7c..e80a7e7c 100644..100755
--- a/CPP/Common/DynLimBuf.h
+++ b/CPP/Common/DynLimBuf.h
diff --git a/CPP/Common/DynamicBuffer.h b/CPP/Common/DynamicBuffer.h
index f6f6b157..f6f6b157 100644..100755
--- a/CPP/Common/DynamicBuffer.h
+++ b/CPP/Common/DynamicBuffer.h
diff --git a/CPP/Common/IntToString.cpp b/CPP/Common/IntToString.cpp
index c87643c8..c87643c8 100644..100755
--- a/CPP/Common/IntToString.cpp
+++ b/CPP/Common/IntToString.cpp
diff --git a/CPP/Common/IntToString.h b/CPP/Common/IntToString.h
index d0a96ef1..d0a96ef1 100644..100755
--- a/CPP/Common/IntToString.h
+++ b/CPP/Common/IntToString.h
diff --git a/CPP/Common/Lang.cpp b/CPP/Common/Lang.cpp
index 35d37525..35d37525 100644..100755
--- a/CPP/Common/Lang.cpp
+++ b/CPP/Common/Lang.cpp
diff --git a/CPP/Common/Lang.h b/CPP/Common/Lang.h
index cc66677d..cc66677d 100644..100755
--- a/CPP/Common/Lang.h
+++ b/CPP/Common/Lang.h
diff --git a/CPP/Common/ListFileUtils.cpp b/CPP/Common/ListFileUtils.cpp
index b361b378..b361b378 100644..100755
--- a/CPP/Common/ListFileUtils.cpp
+++ b/CPP/Common/ListFileUtils.cpp
diff --git a/CPP/Common/ListFileUtils.h b/CPP/Common/ListFileUtils.h
index a91e4b11..a91e4b11 100644..100755
--- a/CPP/Common/ListFileUtils.h
+++ b/CPP/Common/ListFileUtils.h
diff --git a/CPP/Common/LzFindPrepare.cpp b/CPP/Common/LzFindPrepare.cpp
index 8845e4a5..8845e4a5 100644..100755
--- a/CPP/Common/LzFindPrepare.cpp
+++ b/CPP/Common/LzFindPrepare.cpp
diff --git a/CPP/Common/MyBuffer.h b/CPP/Common/MyBuffer.h
index 18ab6fa4..18ab6fa4 100644..100755
--- a/CPP/Common/MyBuffer.h
+++ b/CPP/Common/MyBuffer.h
diff --git a/CPP/Common/MyBuffer2.h b/CPP/Common/MyBuffer2.h
index 372d478c..372d478c 100644..100755
--- a/CPP/Common/MyBuffer2.h
+++ b/CPP/Common/MyBuffer2.h
diff --git a/CPP/Common/MyCom.h b/CPP/Common/MyCom.h
index ce2f0dd1..ff542780 100644..100755
--- a/CPP/Common/MyCom.h
+++ b/CPP/Common/MyCom.h
@@ -67,6 +67,7 @@ public:
template <class Q>
HRESULT QueryInterface(REFGUID iid, Q** pp) const throw()
{
+ // if (*pp) throw 20220216; // for debug
return _p->QueryInterface(iid, (void**)pp);
}
};
diff --git a/CPP/Common/MyException.h b/CPP/Common/MyException.h
index f0ad1115..f0ad1115 100644..100755
--- a/CPP/Common/MyException.h
+++ b/CPP/Common/MyException.h
diff --git a/CPP/Common/MyGuidDef.h b/CPP/Common/MyGuidDef.h
index 38aad6e6..38aad6e6 100644..100755
--- a/CPP/Common/MyGuidDef.h
+++ b/CPP/Common/MyGuidDef.h
diff --git a/CPP/Common/MyInitGuid.h b/CPP/Common/MyInitGuid.h
index 04d77e21..04d77e21 100644..100755
--- a/CPP/Common/MyInitGuid.h
+++ b/CPP/Common/MyInitGuid.h
diff --git a/CPP/Common/MyLinux.h b/CPP/Common/MyLinux.h
index 1a918993..98b453c1 100644..100755
--- a/CPP/Common/MyLinux.h
+++ b/CPP/Common/MyLinux.h
@@ -3,6 +3,18 @@
#ifndef __MY_LIN_LINUX_H
#define __MY_LIN_LINUX_H
+// #include "../../C/7zTypes.h"
+
+#define MY_LIN_DT_UNKNOWN 0
+#define MY_LIN_DT_FIFO 1
+#define MY_LIN_DT_CHR 2
+#define MY_LIN_DT_DIR 4
+#define MY_LIN_DT_BLK 6
+#define MY_LIN_DT_REG 8
+#define MY_LIN_DT_LNK 10
+#define MY_LIN_DT_SOCK 12
+#define MY_LIN_DT_WHT 14
+
#define MY_LIN_S_IFMT 00170000
#define MY_LIN_S_IFSOCK 0140000
#define MY_LIN_S_IFLNK 0120000
@@ -39,4 +51,25 @@
#define MY_LIN_S_IWOTH 00002
#define MY_LIN_S_IXOTH 00001
+/*
+// major/minor encoding for makedev(): MMMMMmmmmmmMMMmm:
+
+inline UInt32 MY_dev_major(UInt64 dev)
+{
+ return ((UInt32)(dev >> 8) & (UInt32)0xfff) | ((UInt32)(dev >> 32) & ~(UInt32)0xfff);
+}
+
+inline UInt32 MY_dev_minor(UInt64 dev)
+{
+ return ((UInt32)(dev) & 0xff) | ((UInt32)(dev >> 12) & ~0xff);
+}
+
+inline UInt64 MY_dev_makedev(UInt32 __major, UInt32 __minor)
+{
+ return (__minor & 0xff) | ((__major & 0xfff) << 8)
+ | ((UInt64) (__minor & ~0xff) << 12)
+ | ((UInt64) (__major & ~0xfff) << 32);
+}
+*/
+
#endif
diff --git a/CPP/Common/MyMap.cpp b/CPP/Common/MyMap.cpp
index 923846ae..923846ae 100644..100755
--- a/CPP/Common/MyMap.cpp
+++ b/CPP/Common/MyMap.cpp
diff --git a/CPP/Common/MyMap.h b/CPP/Common/MyMap.h
index cbcbadd6..cbcbadd6 100644..100755
--- a/CPP/Common/MyMap.h
+++ b/CPP/Common/MyMap.h
diff --git a/CPP/Common/MyString.cpp b/CPP/Common/MyString.cpp
index db202f4c..bf1638eb 100644..100755
--- a/CPP/Common/MyString.cpp
+++ b/CPP/Common/MyString.cpp
@@ -30,8 +30,8 @@ inline const char* MyStringGetNextCharPointer(const char *p) throw()
}
*/
-#define MY_STRING_NEW_char(_size_) MY_STRING_NEW(char, _size_)
-#define MY_STRING_NEW_wchar_t(_size_) MY_STRING_NEW(wchar_t, _size_)
+#define MY_STRING_NEW_char(_size_) MY_STRING_NEW(char, (_size_))
+#define MY_STRING_NEW_wchar_t(_size_) MY_STRING_NEW(wchar_t, (_size_))
int FindCharPosInString(const char *s, char c) throw()
@@ -190,8 +190,8 @@ bool IsString1PrefixedByString2(const char *s1, const char *s2) throw()
{
for (;;)
{
- unsigned char c2 = (unsigned char)*s2++; if (c2 == 0) return true;
- unsigned char c1 = (unsigned char)*s1++; if (c1 != c2) return false;
+ const unsigned char c2 = (unsigned char)*s2++; if (c2 == 0) return true;
+ const unsigned char c1 = (unsigned char)*s1++; if (c1 != c2) return false;
}
}
@@ -199,8 +199,8 @@ bool StringsAreEqualNoCase(const wchar_t *s1, const wchar_t *s2) throw()
{
for (;;)
{
- wchar_t c1 = *s1++;
- wchar_t c2 = *s2++;
+ const wchar_t c1 = *s1++;
+ const wchar_t c2 = *s2++;
if (c1 != c2 && MyCharUpper(c1) != MyCharUpper(c2)) return false;
if (c1 == 0) return true;
}
@@ -213,10 +213,10 @@ bool AString::IsPrefixedBy_Ascii_NoCase(const char *s) const throw()
const char *s1 = _chars;
for (;;)
{
- char c2 = *s++;
+ const char c2 = *s++;
if (c2 == 0)
return true;
- char c1 = *s1++;
+ const char c1 = *s1++;
if (MyCharLower_Ascii(c1) !=
MyCharLower_Ascii(c2))
return false;
@@ -228,10 +228,10 @@ bool UString::IsPrefixedBy_Ascii_NoCase(const char *s) const throw()
const wchar_t *s1 = _chars;
for (;;)
{
- char c2 = *s++;
+ const char c2 = *s++;
if (c2 == 0)
return true;
- wchar_t c1 = *s1++;
+ const wchar_t c1 = *s1++;
if (MyCharLower_Ascii(c1) != (unsigned char)MyCharLower_Ascii(c2))
return false;
}
@@ -241,7 +241,7 @@ bool StringsAreEqual_Ascii(const char *u, const char *a) throw()
{
for (;;)
{
- char c = *a;
+ const char c = *a;
if (c != *u)
return false;
if (c == 0)
@@ -255,7 +255,7 @@ bool StringsAreEqual_Ascii(const wchar_t *u, const char *a) throw()
{
for (;;)
{
- unsigned char c = (unsigned char)*a;
+ const unsigned char c = (unsigned char)*a;
if (c != *u)
return false;
if (c == 0)
@@ -269,8 +269,8 @@ bool StringsAreEqualNoCase_Ascii(const char *s1, const char *s2) throw()
{
for (;;)
{
- char c1 = *s1++;
- char c2 = *s2++;
+ const char c1 = *s1++;
+ const char c2 = *s2++;
if (c1 != c2 && MyCharLower_Ascii(c1) != MyCharLower_Ascii(c2))
return false;
if (c1 == 0)
@@ -282,8 +282,8 @@ bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const wchar_t *s2) throw()
{
for (;;)
{
- wchar_t c1 = *s1++;
- wchar_t c2 = *s2++;
+ const wchar_t c1 = *s1++;
+ const wchar_t c2 = *s2++;
if (c1 != c2 && MyCharLower_Ascii(c1) != MyCharLower_Ascii(c2))
return false;
if (c1 == 0)
@@ -295,8 +295,8 @@ bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const char *s2) throw()
{
for (;;)
{
- wchar_t c1 = *s1++;
- char c2 = *s2++;
+ const wchar_t c1 = *s1++;
+ const char c2 = *s2++;
if (c1 != (unsigned char)c2 && (c1 > 0x7F || MyCharLower_Ascii(c1) != (unsigned char)MyCharLower_Ascii(c2)))
return false;
if (c1 == 0)
@@ -308,8 +308,8 @@ bool IsString1PrefixedByString2(const wchar_t *s1, const wchar_t *s2) throw()
{
for (;;)
{
- wchar_t c2 = *s2++; if (c2 == 0) return true;
- wchar_t c1 = *s1++; if (c1 != c2) return false;
+ const wchar_t c2 = *s2++; if (c2 == 0) return true;
+ const wchar_t c1 = *s1++; if (c1 != c2) return false;
}
}
@@ -317,8 +317,8 @@ bool IsString1PrefixedByString2(const wchar_t *s1, const char *s2) throw()
{
for (;;)
{
- unsigned char c2 = (unsigned char)(*s2++); if (c2 == 0) return true;
- wchar_t c1 = *s1++; if (c1 != c2) return false;
+ const unsigned char c2 = (unsigned char)(*s2++); if (c2 == 0) return true;
+ const wchar_t c1 = *s1++; if (c1 != c2) return false;
}
}
@@ -326,8 +326,8 @@ bool IsString1PrefixedByString2_NoCase_Ascii(const char *s1, const char *s2) thr
{
for (;;)
{
- char c2 = *s2++; if (c2 == 0) return true;
- char c1 = *s1++;
+ const char c2 = *s2++; if (c2 == 0) return true;
+ const char c1 = *s1++;
if (c1 != c2 && MyCharLower_Ascii(c1) != MyCharLower_Ascii(c2))
return false;
}
@@ -337,8 +337,8 @@ bool IsString1PrefixedByString2_NoCase_Ascii(const wchar_t *s1, const char *s2)
{
for (;;)
{
- char c2 = *s2++; if (c2 == 0) return true;
- wchar_t c1 = *s1++;
+ const char c2 = *s2++; if (c2 == 0) return true;
+ const wchar_t c1 = *s1++;
if (c1 != (unsigned char)c2 && MyCharLower_Ascii(c1) != (unsigned char)MyCharLower_Ascii(c2))
return false;
}
@@ -348,8 +348,8 @@ bool IsString1PrefixedByString2_NoCase(const wchar_t *s1, const wchar_t *s2) thr
{
for (;;)
{
- wchar_t c2 = *s2++; if (c2 == 0) return true;
- wchar_t c1 = *s1++;
+ const wchar_t c2 = *s2++; if (c2 == 0) return true;
+ const wchar_t c1 = *s1++;
if (c1 != c2 && MyCharUpper(c1) != MyCharUpper(c2))
return false;
}
@@ -360,12 +360,12 @@ int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2) throw()
{
for (;;)
{
- wchar_t c1 = *s1++;
- wchar_t c2 = *s2++;
+ const wchar_t c1 = *s1++;
+ const wchar_t c2 = *s2++;
if (c1 != c2)
{
- wchar_t u1 = MyCharUpper(c1);
- wchar_t u2 = MyCharUpper(c2);
+ const wchar_t u1 = MyCharUpper(c1);
+ const wchar_t u2 = MyCharUpper(c2);
if (u1 < u2) return -1;
if (u1 > u2) return 1;
}
@@ -401,14 +401,13 @@ void AString::InsertSpace(unsigned &index, unsigned size)
MoveItems(index + size, index);
}
-#define k_Alloc_Len_Limit 0x40000000
+#define k_Alloc_Len_Limit (0x40000000 - 2)
void AString::ReAlloc(unsigned newLimit)
{
- if (newLimit < _len || newLimit >= k_Alloc_Len_Limit) throw 20130220;
- // MY_STRING_REALLOC(_chars, char, newLimit + 1, _len + 1);
- char *newBuf = MY_STRING_NEW_char(newLimit + 1);
- memcpy(newBuf, _chars, (size_t)(_len + 1));
+ // MY_STRING_REALLOC(_chars, char, (size_t)newLimit + 1, (size_t)_len + 1);
+ char *newBuf = MY_STRING_NEW_char((size_t)newLimit + 1);
+ memcpy(newBuf, _chars, (size_t)_len + 1);
MY_STRING_DELETE(_chars);
_chars = newBuf;
_limit = newLimit;
@@ -416,9 +415,9 @@ void AString::ReAlloc(unsigned newLimit)
void AString::ReAlloc2(unsigned newLimit)
{
- if (newLimit >= k_Alloc_Len_Limit) throw 20130220;
- // MY_STRING_REALLOC(_chars, char, newLimit + 1, 0);
- char *newBuf = MY_STRING_NEW_char(newLimit + 1);
+ if (newLimit > k_Alloc_Len_Limit) throw 20130220;
+ // MY_STRING_REALLOC(_chars, char, (size_t)newLimit + 1, 0);
+ char *newBuf = MY_STRING_NEW_char((size_t)newLimit + 1);
newBuf[0] = 0;
MY_STRING_DELETE(_chars);
_chars = newBuf;
@@ -427,8 +426,8 @@ void AString::ReAlloc2(unsigned newLimit)
void AString::SetStartLen(unsigned len)
{
- _chars = 0;
- _chars = MY_STRING_NEW_char(len + 1);
+ _chars = NULL;
+ _chars = MY_STRING_NEW_char((size_t)len + 1);
_len = len;
_limit = len;
}
@@ -439,20 +438,30 @@ void AString::Grow_1()
next += next / 2;
next += 16;
next &= ~(unsigned)15;
- ReAlloc(next - 1);
+ next--;
+ if (next < _len || next > k_Alloc_Len_Limit)
+ next = k_Alloc_Len_Limit;
+ if (next <= _len)
+ throw 20130220;
+ ReAlloc(next);
+ // Grow(1);
}
void AString::Grow(unsigned n)
{
- unsigned freeSize = _limit - _len;
+ const unsigned freeSize = _limit - _len;
if (n <= freeSize)
return;
-
unsigned next = _len + n;
next += next / 2;
next += 16;
next &= ~(unsigned)15;
- ReAlloc(next - 1);
+ next--;
+ if (next < _len || next > k_Alloc_Len_Limit)
+ next = k_Alloc_Len_Limit;
+ if (next <= _len || next - _len < n)
+ throw 20130220;
+ ReAlloc(next);
}
AString::AString(unsigned num, const char *s)
@@ -500,7 +509,7 @@ static const unsigned kStartStringCapacity = 4;
AString::AString()
{
- _chars = 0;
+ _chars = NULL;
_chars = MY_STRING_NEW_char(kStartStringCapacity);
_len = 0;
_limit = kStartStringCapacity - 1;
@@ -548,7 +557,7 @@ AString &AString::operator=(const char *s)
unsigned len = MyStringLen(s);
if (len > _limit)
{
- char *newBuf = MY_STRING_NEW_char(len + 1);
+ char *newBuf = MY_STRING_NEW_char((size_t)len + 1);
MY_STRING_DELETE(_chars);
_chars = newBuf;
_limit = len;
@@ -565,7 +574,7 @@ AString &AString::operator=(const AString &s)
unsigned len = s._len;
if (len > _limit)
{
- char *newBuf = MY_STRING_NEW_char(len + 1);
+ char *newBuf = MY_STRING_NEW_char((size_t)len + 1);
MY_STRING_DELETE(_chars);
_chars = newBuf;
_limit = len;
@@ -590,7 +599,7 @@ void AString::SetFromWStr_if_Ascii(const wchar_t *s)
}
if (len > _limit)
{
- char *newBuf = MY_STRING_NEW_char(len + 1);
+ char *newBuf = MY_STRING_NEW_char((size_t)len + 1);
MY_STRING_DELETE(_chars);
_chars = newBuf;
_limit = len;
@@ -614,7 +623,7 @@ void AString::SetFromBstr_if_Ascii(BSTR s)
}
if (len > _limit)
{
- char *newBuf = MY_STRING_NEW_char(len + 1);
+ char *newBuf = MY_STRING_NEW_char((size_t)len + 1);
MY_STRING_DELETE(_chars);
_chars = newBuf;
_limit = len;
@@ -631,6 +640,7 @@ void AString::SetFromBstr_if_Ascii(BSTR s)
void AString::Add_Space() { operator+=(' '); }
void AString::Add_Space_if_NotEmpty() { if (!IsEmpty()) Add_Space(); }
void AString::Add_LF() { operator+=('\n'); }
+void AString::Add_Slash() { operator+=('/'); }
AString &AString::operator+=(const char *s)
{
@@ -667,11 +677,23 @@ void UString::Add_UInt64(UInt64 v)
_len = (unsigned)(ConvertUInt64ToString(v, _chars + _len) - _chars);
}
+void AString::AddFrom(const char *s, unsigned len) // no check
+{
+ if (len != 0)
+ {
+ Grow(len);
+ memcpy(_chars + _len, s, len);
+ len += _len;
+ _chars[len] = 0;
+ _len = len;
+ }
+}
+
void AString::SetFrom(const char *s, unsigned len) // no check
{
if (len > _limit)
{
- char *newBuf = MY_STRING_NEW_char(len + 1);
+ char *newBuf = MY_STRING_NEW_char((size_t)len + 1);
MY_STRING_DELETE(_chars);
_chars = newBuf;
_limit = len;
@@ -976,9 +998,8 @@ void UString::InsertSpace(unsigned index, unsigned size)
void UString::ReAlloc(unsigned newLimit)
{
- if (newLimit < _len || newLimit >= k_Alloc_Len_Limit) throw 20130221;
- // MY_STRING_REALLOC(_chars, wchar_t, newLimit + 1, _len + 1);
- wchar_t *newBuf = MY_STRING_NEW_wchar_t(newLimit + 1);
+ // MY_STRING_REALLOC(_chars, wchar_t, (size_t)newLimit + 1, (size_t)_len + 1);
+ wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)newLimit + 1);
wmemcpy(newBuf, _chars, _len + 1);
MY_STRING_DELETE(_chars);
_chars = newBuf;
@@ -987,9 +1008,9 @@ void UString::ReAlloc(unsigned newLimit)
void UString::ReAlloc2(unsigned newLimit)
{
- if (newLimit >= k_Alloc_Len_Limit) throw 20130221;
+ if (newLimit > k_Alloc_Len_Limit) throw 20130221;
// MY_STRING_REALLOC(_chars, wchar_t, newLimit + 1, 0);
- wchar_t *newBuf = MY_STRING_NEW_wchar_t(newLimit + 1);
+ wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)newLimit + 1);
newBuf[0] = 0;
MY_STRING_DELETE(_chars);
_chars = newBuf;
@@ -999,7 +1020,7 @@ void UString::ReAlloc2(unsigned newLimit)
void UString::SetStartLen(unsigned len)
{
_chars = 0;
- _chars = MY_STRING_NEW_wchar_t(len + 1);
+ _chars = MY_STRING_NEW_wchar_t((size_t)len + 1);
_len = len;
_limit = len;
}
@@ -1010,19 +1031,28 @@ void UString::Grow_1()
next += next / 2;
next += 16;
next &= ~(unsigned)15;
- ReAlloc(next - 1);
+ next--;
+ if (next < _len || next > k_Alloc_Len_Limit)
+ next = k_Alloc_Len_Limit;
+ if (next <= _len)
+ throw 20130220;
+ ReAlloc(next);
}
void UString::Grow(unsigned n)
{
- unsigned freeSize = _limit - _len;
+ const unsigned freeSize = _limit - _len;
if (n <= freeSize)
return;
-
unsigned next = _len + n;
next += next / 2;
next += 16;
next &= ~(unsigned)15;
+ next--;
+ if (next < _len || next > k_Alloc_Len_Limit)
+ next = k_Alloc_Len_Limit;
+ if (next <= _len || next - _len < n)
+ throw 20130220;
ReAlloc(next - 1);
}
@@ -1149,7 +1179,7 @@ UString &UString::operator=(const wchar_t *s)
unsigned len = MyStringLen(s);
if (len > _limit)
{
- wchar_t *newBuf = MY_STRING_NEW_wchar_t(len + 1);
+ wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)len + 1);
MY_STRING_DELETE(_chars);
_chars = newBuf;
_limit = len;
@@ -1166,7 +1196,7 @@ UString &UString::operator=(const UString &s)
unsigned len = s._len;
if (len > _limit)
{
- wchar_t *newBuf = MY_STRING_NEW_wchar_t(len + 1);
+ wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)len + 1);
MY_STRING_DELETE(_chars);
_chars = newBuf;
_limit = len;
@@ -1180,7 +1210,7 @@ void UString::SetFrom(const wchar_t *s, unsigned len) // no check
{
if (len > _limit)
{
- wchar_t *newBuf = MY_STRING_NEW_wchar_t(len + 1);
+ wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)len + 1);
MY_STRING_DELETE(_chars);
_chars = newBuf;
_limit = len;
@@ -1218,7 +1248,7 @@ void UString::SetFromBstr(LPCOLESTR s)
if (len > _limit)
{
- wchar_t *newBuf = MY_STRING_NEW_wchar_t(len + 1);
+ wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)len + 1);
MY_STRING_DELETE(_chars);
_chars = newBuf;
_limit = len;
@@ -1258,7 +1288,7 @@ UString &UString::operator=(const char *s)
unsigned len = MyStringLen(s);
if (len > _limit)
{
- wchar_t *newBuf = MY_STRING_NEW_wchar_t(len + 1);
+ wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)len + 1);
MY_STRING_DELETE(_chars);
_chars = newBuf;
_limit = len;
@@ -1566,15 +1596,24 @@ void UString::DeleteFrontal(unsigned num) throw()
void UString2::ReAlloc2(unsigned newLimit)
{
- if (newLimit >= k_Alloc_Len_Limit) throw 20130221;
+ // wrong (_len) is allowed after this function
+ if (newLimit > k_Alloc_Len_Limit) throw 20130221;
// MY_STRING_REALLOC(_chars, wchar_t, newLimit + 1, 0);
- _chars = MY_STRING_NEW_wchar_t(newLimit + 1);
+ if (_chars)
+ {
+ MY_STRING_DELETE(_chars);
+ _chars = NULL;
+ // _len = 0;
+ }
+ _chars = MY_STRING_NEW_wchar_t((size_t)newLimit + 1);
+ _chars[0] = 0;
+ // _len = newLimit;
}
void UString2::SetStartLen(unsigned len)
{
- _chars = 0;
- _chars = MY_STRING_NEW_wchar_t(len + 1);
+ _chars = NULL;
+ _chars = MY_STRING_NEW_wchar_t((size_t)len + 1);
_len = len;
}
@@ -1591,7 +1630,7 @@ UString2::UString2(wchar_t c)
UString2::UString2(const wchar_t *s)
{
- unsigned len = MyStringLen(s);
+ const unsigned len = MyStringLen(s);
SetStartLen(len);
wmemcpy(_chars, s, len + 1);
}
@@ -1628,7 +1667,7 @@ UString2 &UString2::operator=(const wchar_t *s)
unsigned len = MyStringLen(s);
if (len > _len)
{
- wchar_t *newBuf = MY_STRING_NEW_wchar_t(len + 1);
+ wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)len + 1);
if (_chars)
MY_STRING_DELETE(_chars);
_chars = newBuf;
@@ -1643,7 +1682,7 @@ void UString2::SetFromAscii(const char *s)
unsigned len = MyStringLen(s);
if (len > _len)
{
- wchar_t *newBuf = MY_STRING_NEW_wchar_t(len + 1);
+ wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)len + 1);
if (_chars)
MY_STRING_DELETE(_chars);
_chars = newBuf;
@@ -1662,7 +1701,7 @@ UString2 &UString2::operator=(const UString2 &s)
unsigned len = s._len;
if (len > _len)
{
- wchar_t *newBuf = MY_STRING_NEW_wchar_t(len + 1);
+ wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)len + 1);
if (_chars)
MY_STRING_DELETE(_chars);
_chars = newBuf;
diff --git a/CPP/Common/MyString.h b/CPP/Common/MyString.h
index aa3c301a..c777c8c3 100644..100755
--- a/CPP/Common/MyString.h
+++ b/CPP/Common/MyString.h
@@ -378,6 +378,7 @@ public:
void Add_Space_if_NotEmpty();
void Add_OptSpaced(const char *s);
void Add_LF();
+ void Add_Slash();
void Add_PathSepar() { operator+=(CHAR_PATH_SEPARATOR); }
AString &operator+=(const char *s);
@@ -386,12 +387,12 @@ public:
void Add_UInt32(UInt32 v);
void Add_UInt64(UInt64 v);
+ void AddFrom(const char *s, unsigned len); // no check
void SetFrom(const char *s, unsigned len); // no check
void SetFrom_CalcLen(const char *s, unsigned len);
AString Mid(unsigned startIndex, unsigned count) const { return AString(count, _chars + startIndex); }
AString Left(unsigned count) const { return AString(count, *this); }
-
// void MakeUpper() { MyStringUpper(_chars); }
// void MakeLower() { MyStringLower(_chars); }
void MakeLower_Ascii() { MyStringLower_Ascii(_chars); }
diff --git a/CPP/Common/MyTypes.h b/CPP/Common/MyTypes.h
index 71b8e7fa..71b8e7fa 100644..100755
--- a/CPP/Common/MyTypes.h
+++ b/CPP/Common/MyTypes.h
diff --git a/CPP/Common/MyUnknown.h b/CPP/Common/MyUnknown.h
index ff025cb5..ff025cb5 100644..100755
--- a/CPP/Common/MyUnknown.h
+++ b/CPP/Common/MyUnknown.h
diff --git a/CPP/Common/MyVector.cpp b/CPP/Common/MyVector.cpp
index 0b1baf45..0b1baf45 100644..100755
--- a/CPP/Common/MyVector.cpp
+++ b/CPP/Common/MyVector.cpp
diff --git a/CPP/Common/MyVector.h b/CPP/Common/MyVector.h
index c8512342..3417a176 100644..100755
--- a/CPP/Common/MyVector.h
+++ b/CPP/Common/MyVector.h
@@ -5,6 +5,8 @@
#include <string.h>
+const unsigned k_VectorSizeMax = ((unsigned)1 << 31) - 1;
+
template <class T>
class CRecordVector
{
@@ -17,31 +19,41 @@ class CRecordVector
memmove(_items + destIndex, _items + srcIndex, (size_t)(_size - srcIndex) * sizeof(T));
}
- void ReserveOnePosition()
+ void ReAllocForNewCapacity(const unsigned newCapacity)
{
- if (_size == _capacity)
- {
- unsigned newCapacity = _capacity + (_capacity >> 2) + 1;
- T *p;
- MY_ARRAY_NEW(p, T, newCapacity);
- // p = new T[newCapacity];
- if (_size != 0)
- memcpy(p, _items, (size_t)_size * sizeof(T));
- delete []_items;
- _items = p;
- _capacity = newCapacity;
- }
+ T *p;
+ MY_ARRAY_NEW(p, T, newCapacity);
+ // p = new T[newCapacity];
+ if (_size != 0)
+ memcpy(p, _items, (size_t)_size * sizeof(T));
+ delete []_items;
+ _items = p;
+ _capacity = newCapacity;
}
public:
+ void ReserveOnePosition()
+ {
+ if (_size != _capacity)
+ return;
+ if (_capacity >= k_VectorSizeMax)
+ throw 2021;
+ const unsigned rem = k_VectorSizeMax - _capacity;
+ unsigned add = (_capacity >> 2) + 1;
+ if (add > rem)
+ add = rem;
+ ReAllocForNewCapacity(_capacity + add);
+ }
+
CRecordVector(): _items(NULL), _size(0), _capacity(0) {}
- CRecordVector(const CRecordVector &v): _items(0), _size(0), _capacity(0)
+ CRecordVector(const CRecordVector &v): _items(NULL), _size(0), _capacity(0)
{
- unsigned size = v.Size();
+ const unsigned size = v.Size();
if (size != 0)
{
+ // MY_ARRAY_NEW(_items, T, size)
_items = new T[size];
_size = size;
_capacity = size;
@@ -66,22 +78,25 @@ public:
{
if (newCapacity > _capacity)
{
- T *p;
- MY_ARRAY_NEW(p, T, newCapacity);
- // p = new T[newCapacity];
- if (_size != 0)
- memcpy(p, _items, (size_t)_size * sizeof(T));
- delete []_items;
- _items = p;
- _capacity = newCapacity;
+ if (newCapacity > k_VectorSizeMax)
+ throw 2021;
+ ReAllocForNewCapacity(newCapacity);
}
}
+ void ChangeSize_KeepData(unsigned newSize)
+ {
+ Reserve(newSize);
+ _size = newSize;
+ }
+
void ClearAndReserve(unsigned newCapacity)
{
Clear();
if (newCapacity > _capacity)
{
+ if (newCapacity > k_VectorSizeMax)
+ throw 2021;
delete []_items;
_items = NULL;
_capacity = 0;
@@ -97,22 +112,6 @@ public:
_size = newSize;
}
- void ChangeSize_KeepData(unsigned newSize)
- {
- if (newSize > _capacity)
- {
- T *p;
- MY_ARRAY_NEW(p, T, newSize)
- // p = new T[newSize];
- if (_size != 0)
- memcpy(p, _items, (size_t)_size * sizeof(T));
- delete []_items;
- _items = p;
- _capacity = newSize;
- }
- _size = newSize;
- }
-
void ReserveDown()
{
if (_size == _capacity)
@@ -120,6 +119,7 @@ public:
T *p = NULL;
if (_size != 0)
{
+ // MY_ARRAY_NEW(p, T, _size)
p = new T[_size];
memcpy(p, _items, (size_t)_size * sizeof(T));
}
@@ -178,7 +178,7 @@ public:
{
if (&v == this)
return *this;
- unsigned size = v.Size();
+ const unsigned size = v.Size();
if (size > _capacity)
{
delete []_items;
@@ -196,24 +196,45 @@ public:
CRecordVector& operator+=(const CRecordVector &v)
{
- unsigned size = v.Size();
- Reserve(_size + size);
+ const unsigned size = v.Size();
if (size != 0)
+ {
+ if (_size >= k_VectorSizeMax || size > k_VectorSizeMax - _size)
+ throw 2021;
+ const unsigned newSize = _size + size;
+ Reserve(newSize);
memcpy(_items + _size, v._items, (size_t)size * sizeof(T));
- _size += size;
+ _size = newSize;
+ }
return *this;
}
unsigned Add(const T item)
{
ReserveOnePosition();
- _items[_size] = item;
- return _size++;
+ const unsigned size = _size;
+ _size = size + 1;
+ _items[size] = item;
+ return size;
+ }
+
+ /*
+ unsigned Add2(const T &item)
+ {
+ ReserveOnePosition();
+ const unsigned size = _size;
+ _size = size + 1;
+ _items[size] = item;
+ return size;
}
+ */
- void AddInReserved(const T item)
+ unsigned AddInReserved(const T item)
{
- _items[_size++] = item;
+ const unsigned size = _size;
+ _size = size + 1;
+ _items[size] = item;
+ return size;
}
void Insert(unsigned index, const T item)
@@ -224,6 +245,13 @@ public:
_size++;
}
+ void InsertInReserved(unsigned index, const T item)
+ {
+ MoveItems(index + 1, index);
+ _items[index] = item;
+ _size++;
+ }
+
void MoveToFront(unsigned index)
{
if (index != 0)
@@ -254,7 +282,8 @@ public:
{
while (left != right)
{
- unsigned mid = (left + right) / 2;
+ // const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2);
+ const unsigned mid = (left + right) / 2;
const T midVal = (*this)[mid];
if (item == midVal)
return (int)mid;
@@ -270,9 +299,10 @@ public:
{
while (left != right)
{
- unsigned mid = (left + right) / 2;
+ // const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2);
+ const unsigned mid = (left + right) / 2;
const T& midVal = (*this)[mid];
- int comp = item.Compare(midVal);
+ const int comp = item.Compare(midVal);
if (comp == 0)
return (int)mid;
if (comp < 0)
@@ -298,7 +328,8 @@ public:
unsigned left = 0, right = _size;
while (left != right)
{
- unsigned mid = (left + right) / 2;
+ // const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2);
+ const unsigned mid = (left + right) / 2;
const T midVal = (*this)[mid];
if (item == midVal)
return mid;
@@ -316,9 +347,10 @@ public:
unsigned left = 0, right = _size;
while (left != right)
{
- unsigned mid = (left + right) / 2;
+ // const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2);
+ const unsigned mid = (left + right) / 2;
const T& midVal = (*this)[mid];
- int comp = item.Compare(midVal);
+ const int comp = item.Compare(midVal);
if (comp == 0)
return mid;
if (comp < 0)
@@ -431,29 +463,35 @@ public:
CObjectVector() {}
CObjectVector(const CObjectVector &v)
{
- unsigned size = v.Size();
+ const unsigned size = v.Size();
_v.ConstructReserve(size);
for (unsigned i = 0; i < size; i++)
- _v.AddInReserved(new T(v[i]));
+ AddInReserved(v[i]);
}
CObjectVector& operator=(const CObjectVector &v)
{
if (&v == this)
return *this;
Clear();
- unsigned size = v.Size();
+ const unsigned size = v.Size();
_v.Reserve(size);
for (unsigned i = 0; i < size; i++)
- _v.AddInReserved(new T(v[i]));
+ AddInReserved(v[i]);
return *this;
}
CObjectVector& operator+=(const CObjectVector &v)
{
- unsigned size = v.Size();
- _v.Reserve(Size() + size);
- for (unsigned i = 0; i < size; i++)
- _v.AddInReserved(new T(v[i]));
+ const unsigned addSize = v.Size();
+ if (addSize != 0)
+ {
+ const unsigned size = Size();
+ if (size >= k_VectorSizeMax || addSize > k_VectorSizeMax - size)
+ throw 2021;
+ _v.Reserve(size + addSize);
+ for (unsigned i = 0; i < addSize; i++)
+ AddInReserved(v[i]);
+ }
return *this;
}
@@ -466,14 +504,37 @@ public:
void MoveToFront(unsigned index) { _v.MoveToFront(index); }
- unsigned Add(const T& item) { return _v.Add(new T(item)); }
+ unsigned Add(const T& item)
+ {
+ _v.ReserveOnePosition();
+ return AddInReserved(item);
+ }
+
+ unsigned AddInReserved(const T& item)
+ {
+ return _v.AddInReserved(new T(item));
+ }
+
+ void ReserveOnePosition()
+ {
+ _v.ReserveOnePosition();
+ }
+
+ unsigned AddInReserved_Ptr_of_new(T *ptr)
+ {
+ return _v.AddInReserved(ptr);
+ }
+
+ #define VECTOR_ADD_NEW_OBJECT(v, a) \
+ (v).ReserveOnePosition(); \
+ (v).AddInReserved_Ptr_of_new(new a);
- void AddInReserved(const T& item) { _v.AddInReserved(new T(item)); }
T& AddNew()
{
+ _v.ReserveOnePosition();
T *p = new T;
- _v.Add(p);
+ _v.AddInReserved(p);
return *p;
}
@@ -484,12 +545,17 @@ public:
return *p;
}
- void Insert(unsigned index, const T& item) { _v.Insert(index, new T(item)); }
+ void Insert(unsigned index, const T& item)
+ {
+ _v.ReserveOnePosition();
+ _v.InsertInReserved(index, new T(item));
+ }
T& InsertNew(unsigned index)
{
+ _v.ReserveOnePosition();
T *p = new T;
- _v.Insert(index, p);
+ _v.InsertInReserved(index, p);
return *p;
}
@@ -514,7 +580,7 @@ public:
void DeleteFrom(unsigned index)
{
- unsigned size = _v.Size();
+ const unsigned size = _v.Size();
for (unsigned i = index; i < size; i++)
delete (T *)_v[i];
_v.DeleteFrom(index);
@@ -564,9 +630,10 @@ public:
unsigned left = 0, right = Size();
while (left != right)
{
- unsigned mid = (left + right) / 2;
+ // const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2);
+ const unsigned mid = (left + right) / 2;
const T& midVal = (*this)[mid];
- int comp = item.Compare(midVal);
+ const int comp = item.Compare(midVal);
if (comp == 0)
return (int)mid;
if (comp < 0)
@@ -582,9 +649,10 @@ public:
unsigned left = 0, right = Size();
while (left != right)
{
- unsigned mid = (left + right) / 2;
+ // const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2);
+ const unsigned mid = (left + right) / 2;
const T& midVal = (*this)[mid];
- int comp = item.Compare(midVal);
+ const int comp = item.Compare(midVal);
if (comp == 0)
return mid;
if (comp < 0)
@@ -602,9 +670,10 @@ public:
unsigned left = 0, right = Size();
while (left != right)
{
- unsigned mid = (left + right) / 2;
+ // const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2);
+ const unsigned mid = (left + right) / 2;
const T& midVal = (*this)[mid];
- int comp = item.Compare(midVal);
+ const int comp = item.Compare(midVal);
if (comp == 0)
{
right = mid + 1;
diff --git a/CPP/Common/MyWindows.cpp b/CPP/Common/MyWindows.cpp
index 88f312fb..88f312fb 100644..100755
--- a/CPP/Common/MyWindows.cpp
+++ b/CPP/Common/MyWindows.cpp
diff --git a/CPP/Common/MyWindows.h b/CPP/Common/MyWindows.h
index 0664a5e0..15db5243 100644..100755
--- a/CPP/Common/MyWindows.h
+++ b/CPP/Common/MyWindows.h
@@ -76,7 +76,6 @@ typedef struct _FILETIME
DWORD dwHighDateTime;
} FILETIME;
-#define HRESULT LONG
#define SUCCEEDED(hr) ((HRESULT)(hr) >= 0)
#define FAILED(hr) ((HRESULT)(hr) < 0)
typedef ULONG PROPID;
@@ -150,6 +149,7 @@ enum VARENUM
VT_VARIANT = 12,
VT_UNKNOWN = 13,
VT_DECIMAL = 14,
+
VT_I1 = 16,
VT_UI1 = 17,
VT_UI2 = 18,
diff --git a/CPP/Common/MyXml.cpp b/CPP/Common/MyXml.cpp
index e0145188..e0145188 100644..100755
--- a/CPP/Common/MyXml.cpp
+++ b/CPP/Common/MyXml.cpp
diff --git a/CPP/Common/MyXml.h b/CPP/Common/MyXml.h
index 00b7113a..00b7113a 100644..100755
--- a/CPP/Common/MyXml.h
+++ b/CPP/Common/MyXml.h
diff --git a/CPP/Common/NewHandler.cpp b/CPP/Common/NewHandler.cpp
index 7e5b1d45..65ef41d4 100644..100755
--- a/CPP/Common/NewHandler.cpp
+++ b/CPP/Common/NewHandler.cpp
@@ -97,19 +97,33 @@ const int kDebugSize = 1000000;
static void *a[kDebugSize];
static int index = 0;
+static bool wasInit = false;
+static CRITICAL_SECTION cs;
+
static int numAllocs = 0;
void * __cdecl operator new(size_t size)
{
+ if (!wasInit)
+ {
+ InitializeCriticalSection(&cs);
+ wasInit = true;
+ }
+ EnterCriticalSection(&cs);
+
numAllocs++;
+ int loc = numAllocs;
void *p = HeapAlloc(GetProcessHeap(), 0, size);
+ /*
if (index < kDebugSize)
{
a[index] = p;
index++;
}
+ */
+ printf("Alloc %6d, size = %8u\n", loc, (unsigned)size);
+ LeaveCriticalSection(&cs);
if (p == 0)
throw CNewException();
- printf("Alloc %6d, size = %8u\n", numAllocs, (unsigned)size);
return p;
}
@@ -123,6 +137,7 @@ public:
}
~CC()
{
+ printf("\nDestructor: %d\n", numAllocs);
for (int i = 0; i < kDebugSize; i++)
if (a[i] != 0)
return;
@@ -134,6 +149,7 @@ void __cdecl operator delete(void *p)
{
if (p == 0)
return;
+ EnterCriticalSection(&cs);
/*
for (int i = 0; i < index; i++)
if (a[i] == p)
@@ -142,6 +158,7 @@ void __cdecl operator delete(void *p)
HeapFree(GetProcessHeap(), 0, p);
numAllocs--;
printf("Free %d\n", numAllocs);
+ LeaveCriticalSection(&cs);
}
#endif
diff --git a/CPP/Common/NewHandler.h b/CPP/Common/NewHandler.h
index aedeca64..aedeca64 100644..100755
--- a/CPP/Common/NewHandler.h
+++ b/CPP/Common/NewHandler.h
diff --git a/CPP/Common/Random.cpp b/CPP/Common/Random.cpp
index fbdb8c97..fbdb8c97 100644..100755
--- a/CPP/Common/Random.cpp
+++ b/CPP/Common/Random.cpp
diff --git a/CPP/Common/Random.h b/CPP/Common/Random.h
index e784e984..e784e984 100644..100755
--- a/CPP/Common/Random.h
+++ b/CPP/Common/Random.h
diff --git a/CPP/Common/Sha1Prepare.cpp b/CPP/Common/Sha1Prepare.cpp
index 2652f009..2652f009 100644..100755
--- a/CPP/Common/Sha1Prepare.cpp
+++ b/CPP/Common/Sha1Prepare.cpp
diff --git a/CPP/Common/Sha1Reg.cpp b/CPP/Common/Sha1Reg.cpp
index 0cb2baf7..0cb2baf7 100644..100755
--- a/CPP/Common/Sha1Reg.cpp
+++ b/CPP/Common/Sha1Reg.cpp
diff --git a/CPP/Common/Sha256Prepare.cpp b/CPP/Common/Sha256Prepare.cpp
index 1ec242b5..1ec242b5 100644..100755
--- a/CPP/Common/Sha256Prepare.cpp
+++ b/CPP/Common/Sha256Prepare.cpp
diff --git a/CPP/Common/Sha256Reg.cpp b/CPP/Common/Sha256Reg.cpp
index 5f3a35b0..5f3a35b0 100644..100755
--- a/CPP/Common/Sha256Reg.cpp
+++ b/CPP/Common/Sha256Reg.cpp
diff --git a/CPP/Common/StdAfx.h b/CPP/Common/StdAfx.h
index 420f5c32..420f5c32 100644..100755
--- a/CPP/Common/StdAfx.h
+++ b/CPP/Common/StdAfx.h
diff --git a/CPP/Common/StdInStream.cpp b/CPP/Common/StdInStream.cpp
index abad34b6..abad34b6 100644..100755
--- a/CPP/Common/StdInStream.cpp
+++ b/CPP/Common/StdInStream.cpp
diff --git a/CPP/Common/StdInStream.h b/CPP/Common/StdInStream.h
index 71578eb4..71578eb4 100644..100755
--- a/CPP/Common/StdInStream.h
+++ b/CPP/Common/StdInStream.h
diff --git a/CPP/Common/StdOutStream.cpp b/CPP/Common/StdOutStream.cpp
index 40799e22..40799e22 100644..100755
--- a/CPP/Common/StdOutStream.cpp
+++ b/CPP/Common/StdOutStream.cpp
diff --git a/CPP/Common/StdOutStream.h b/CPP/Common/StdOutStream.h
index 93f1dfa4..93f1dfa4 100644..100755
--- a/CPP/Common/StdOutStream.h
+++ b/CPP/Common/StdOutStream.h
diff --git a/CPP/Common/StringConvert.cpp b/CPP/Common/StringConvert.cpp
index c0bde0fa..c0bde0fa 100644..100755
--- a/CPP/Common/StringConvert.cpp
+++ b/CPP/Common/StringConvert.cpp
diff --git a/CPP/Common/StringConvert.h b/CPP/Common/StringConvert.h
index 865c0254..865c0254 100644..100755
--- a/CPP/Common/StringConvert.h
+++ b/CPP/Common/StringConvert.h
diff --git a/CPP/Common/StringToInt.cpp b/CPP/Common/StringToInt.cpp
index 839867a4..bc4926e5 100644..100755
--- a/CPP/Common/StringToInt.cpp
+++ b/CPP/Common/StringToInt.cpp
@@ -26,6 +26,33 @@ CONVERT_STRING_TO_UINT_FUNC(UInt32, wchar_t, wchar_t)
CONVERT_STRING_TO_UINT_FUNC(UInt64, char, Byte)
CONVERT_STRING_TO_UINT_FUNC(UInt64, wchar_t, wchar_t)
+/*
+Int32 ConvertStringToInt32(const char *s, const char **end) throw()
+{
+ if (end)
+ *end = s;
+ const char *s2 = s;
+ if (*s == '-')
+ s2++;
+ if (*s2 == 0)
+ return 0;
+ const char *end2;
+ UInt32 res = ConvertStringToUInt32(s2, &end2);
+ if (*s == '-')
+ {
+ if (res > ((UInt32)1 << (32 - 1)))
+ return 0;
+ }
+ else if ((res & ((UInt32)1 << (32 - 1))) != 0)
+ return 0;
+ if (end)
+ *end = end2;
+ if (*s == '-')
+ return -(Int32)res;
+ return (Int32)res;
+}
+*/
+
Int32 ConvertStringToInt32(const wchar_t *s, const wchar_t **end) throw()
{
if (end)
diff --git a/CPP/Common/StringToInt.h b/CPP/Common/StringToInt.h
index 5c5d7d7f..4057e494 100644..100755
--- a/CPP/Common/StringToInt.h
+++ b/CPP/Common/StringToInt.h
@@ -10,6 +10,7 @@ UInt64 ConvertStringToUInt64(const char *s, const char **end) throw();
UInt32 ConvertStringToUInt32(const wchar_t *s, const wchar_t **end) throw();
UInt64 ConvertStringToUInt64(const wchar_t *s, const wchar_t **end) throw();
+// Int32 ConvertStringToInt32(const char *s, const char **end) throw();
Int32 ConvertStringToInt32(const wchar_t *s, const wchar_t **end) throw();
UInt32 ConvertOctStringToUInt32(const char *s, const char **end) throw();
diff --git a/CPP/Common/TextConfig.cpp b/CPP/Common/TextConfig.cpp
index 1428aab5..1428aab5 100644..100755
--- a/CPP/Common/TextConfig.cpp
+++ b/CPP/Common/TextConfig.cpp
diff --git a/CPP/Common/TextConfig.h b/CPP/Common/TextConfig.h
index cc7ce412..cc7ce412 100644..100755
--- a/CPP/Common/TextConfig.h
+++ b/CPP/Common/TextConfig.h
diff --git a/CPP/Common/UTFConvert.cpp b/CPP/Common/UTFConvert.cpp
index ac069dba..ac069dba 100644..100755
--- a/CPP/Common/UTFConvert.cpp
+++ b/CPP/Common/UTFConvert.cpp
diff --git a/CPP/Common/UTFConvert.h b/CPP/Common/UTFConvert.h
index 37c4975a..37c4975a 100644..100755
--- a/CPP/Common/UTFConvert.h
+++ b/CPP/Common/UTFConvert.h
diff --git a/CPP/Common/Wildcard.cpp b/CPP/Common/Wildcard.cpp
index 861f3f71..861f3f71 100644..100755
--- a/CPP/Common/Wildcard.cpp
+++ b/CPP/Common/Wildcard.cpp
diff --git a/CPP/Common/Wildcard.h b/CPP/Common/Wildcard.h
index 0fa48873..0fa48873 100644..100755
--- a/CPP/Common/Wildcard.h
+++ b/CPP/Common/Wildcard.h
diff --git a/CPP/Common/XzCrc64Init.cpp b/CPP/Common/XzCrc64Init.cpp
index 5cb8e674..5cb8e674 100644..100755
--- a/CPP/Common/XzCrc64Init.cpp
+++ b/CPP/Common/XzCrc64Init.cpp
diff --git a/CPP/Common/XzCrc64Reg.cpp b/CPP/Common/XzCrc64Reg.cpp
index 33b52493..33b52493 100644..100755
--- a/CPP/Common/XzCrc64Reg.cpp
+++ b/CPP/Common/XzCrc64Reg.cpp
diff --git a/CPP/Windows/COM.cpp b/CPP/Windows/COM.cpp
index d0cb3211..d0cb3211 100644..100755
--- a/CPP/Windows/COM.cpp
+++ b/CPP/Windows/COM.cpp
diff --git a/CPP/Windows/COM.h b/CPP/Windows/COM.h
index cee7f702..cee7f702 100644..100755
--- a/CPP/Windows/COM.h
+++ b/CPP/Windows/COM.h
diff --git a/CPP/Windows/Clipboard.cpp b/CPP/Windows/Clipboard.cpp
index bc7e201d..bc7e201d 100644..100755
--- a/CPP/Windows/Clipboard.cpp
+++ b/CPP/Windows/Clipboard.cpp
diff --git a/CPP/Windows/Clipboard.h b/CPP/Windows/Clipboard.h
index 60fedc13..60fedc13 100644..100755
--- a/CPP/Windows/Clipboard.h
+++ b/CPP/Windows/Clipboard.h
diff --git a/CPP/Windows/CommonDialog.cpp b/CPP/Windows/CommonDialog.cpp
index eaaecada..eaaecada 100644..100755
--- a/CPP/Windows/CommonDialog.cpp
+++ b/CPP/Windows/CommonDialog.cpp
diff --git a/CPP/Windows/CommonDialog.h b/CPP/Windows/CommonDialog.h
index aaf17ac5..aaf17ac5 100644..100755
--- a/CPP/Windows/CommonDialog.h
+++ b/CPP/Windows/CommonDialog.h
diff --git a/CPP/Windows/Console.cpp b/CPP/Windows/Console.cpp
index 28ba1c47..28ba1c47 100644..100755
--- a/CPP/Windows/Console.cpp
+++ b/CPP/Windows/Console.cpp
diff --git a/CPP/Windows/Console.h b/CPP/Windows/Console.h
index 43e02fa6..43e02fa6 100644..100755
--- a/CPP/Windows/Console.h
+++ b/CPP/Windows/Console.h
diff --git a/CPP/Windows/Control/ComboBox.cpp b/CPP/Windows/Control/ComboBox.cpp
index f6ed8d34..f6ed8d34 100644..100755
--- a/CPP/Windows/Control/ComboBox.cpp
+++ b/CPP/Windows/Control/ComboBox.cpp
diff --git a/CPP/Windows/Control/ComboBox.h b/CPP/Windows/Control/ComboBox.h
index f08b1f7c..f08b1f7c 100644..100755
--- a/CPP/Windows/Control/ComboBox.h
+++ b/CPP/Windows/Control/ComboBox.h
diff --git a/CPP/Windows/Control/CommandBar.h b/CPP/Windows/Control/CommandBar.h
index a6197447..a6197447 100644..100755
--- a/CPP/Windows/Control/CommandBar.h
+++ b/CPP/Windows/Control/CommandBar.h
diff --git a/CPP/Windows/Control/Dialog.cpp b/CPP/Windows/Control/Dialog.cpp
index 9ddd2342..9ddd2342 100644..100755
--- a/CPP/Windows/Control/Dialog.cpp
+++ b/CPP/Windows/Control/Dialog.cpp
diff --git a/CPP/Windows/Control/Dialog.h b/CPP/Windows/Control/Dialog.h
index 8a39e996..8a39e996 100644..100755
--- a/CPP/Windows/Control/Dialog.h
+++ b/CPP/Windows/Control/Dialog.h
diff --git a/CPP/Windows/Control/Edit.h b/CPP/Windows/Control/Edit.h
index 51a22c53..51a22c53 100644..100755
--- a/CPP/Windows/Control/Edit.h
+++ b/CPP/Windows/Control/Edit.h
diff --git a/CPP/Windows/Control/ImageList.cpp b/CPP/Windows/Control/ImageList.cpp
index 3e22b956..3e22b956 100644..100755
--- a/CPP/Windows/Control/ImageList.cpp
+++ b/CPP/Windows/Control/ImageList.cpp
diff --git a/CPP/Windows/Control/ImageList.h b/CPP/Windows/Control/ImageList.h
index 19feb117..19feb117 100644..100755
--- a/CPP/Windows/Control/ImageList.h
+++ b/CPP/Windows/Control/ImageList.h
diff --git a/CPP/Windows/Control/ListView.cpp b/CPP/Windows/Control/ListView.cpp
index 16cfd396..16cfd396 100644..100755
--- a/CPP/Windows/Control/ListView.cpp
+++ b/CPP/Windows/Control/ListView.cpp
diff --git a/CPP/Windows/Control/ListView.h b/CPP/Windows/Control/ListView.h
index a13b1041..a13b1041 100644..100755
--- a/CPP/Windows/Control/ListView.h
+++ b/CPP/Windows/Control/ListView.h
diff --git a/CPP/Windows/Control/ProgressBar.h b/CPP/Windows/Control/ProgressBar.h
index 03743067..03743067 100644..100755
--- a/CPP/Windows/Control/ProgressBar.h
+++ b/CPP/Windows/Control/ProgressBar.h
diff --git a/CPP/Windows/Control/PropertyPage.cpp b/CPP/Windows/Control/PropertyPage.cpp
index ce8696d4..ce8696d4 100644..100755
--- a/CPP/Windows/Control/PropertyPage.cpp
+++ b/CPP/Windows/Control/PropertyPage.cpp
diff --git a/CPP/Windows/Control/PropertyPage.h b/CPP/Windows/Control/PropertyPage.h
index b68fd8fe..b68fd8fe 100644..100755
--- a/CPP/Windows/Control/PropertyPage.h
+++ b/CPP/Windows/Control/PropertyPage.h
diff --git a/CPP/Windows/Control/ReBar.h b/CPP/Windows/Control/ReBar.h
index c2d58dbe..c2d58dbe 100644..100755
--- a/CPP/Windows/Control/ReBar.h
+++ b/CPP/Windows/Control/ReBar.h
diff --git a/CPP/Windows/Control/Static.h b/CPP/Windows/Control/Static.h
index 5523b2e6..5523b2e6 100644..100755
--- a/CPP/Windows/Control/Static.h
+++ b/CPP/Windows/Control/Static.h
diff --git a/CPP/Windows/Control/StatusBar.h b/CPP/Windows/Control/StatusBar.h
index 988b8470..988b8470 100644..100755
--- a/CPP/Windows/Control/StatusBar.h
+++ b/CPP/Windows/Control/StatusBar.h
diff --git a/CPP/Windows/Control/StdAfx.h b/CPP/Windows/Control/StdAfx.h
index 1cbd7fea..1cbd7fea 100644..100755
--- a/CPP/Windows/Control/StdAfx.h
+++ b/CPP/Windows/Control/StdAfx.h
diff --git a/CPP/Windows/Control/ToolBar.h b/CPP/Windows/Control/ToolBar.h
index 7bc93a24..7bc93a24 100644..100755
--- a/CPP/Windows/Control/ToolBar.h
+++ b/CPP/Windows/Control/ToolBar.h
diff --git a/CPP/Windows/Control/Trackbar.h b/CPP/Windows/Control/Trackbar.h
index 313e0c85..313e0c85 100644..100755
--- a/CPP/Windows/Control/Trackbar.h
+++ b/CPP/Windows/Control/Trackbar.h
diff --git a/CPP/Windows/Control/Window2.cpp b/CPP/Windows/Control/Window2.cpp
index 994d96e0..994d96e0 100644..100755
--- a/CPP/Windows/Control/Window2.cpp
+++ b/CPP/Windows/Control/Window2.cpp
diff --git a/CPP/Windows/Control/Window2.h b/CPP/Windows/Control/Window2.h
index 7ac580cb..7ac580cb 100644..100755
--- a/CPP/Windows/Control/Window2.h
+++ b/CPP/Windows/Control/Window2.h
diff --git a/CPP/Windows/DLL.cpp b/CPP/Windows/DLL.cpp
index cf5d01a3..cf5d01a3 100644..100755
--- a/CPP/Windows/DLL.cpp
+++ b/CPP/Windows/DLL.cpp
diff --git a/CPP/Windows/DLL.h b/CPP/Windows/DLL.h
index 0c093eed..0c093eed 100644..100755
--- a/CPP/Windows/DLL.h
+++ b/CPP/Windows/DLL.h
diff --git a/CPP/Windows/Defs.h b/CPP/Windows/Defs.h
index 1d96078d..1d96078d 100644..100755
--- a/CPP/Windows/Defs.h
+++ b/CPP/Windows/Defs.h
diff --git a/CPP/Windows/ErrorMsg.cpp b/CPP/Windows/ErrorMsg.cpp
index f6343a5c..f6343a5c 100644..100755
--- a/CPP/Windows/ErrorMsg.cpp
+++ b/CPP/Windows/ErrorMsg.cpp
diff --git a/CPP/Windows/ErrorMsg.h b/CPP/Windows/ErrorMsg.h
index 01204eb9..01204eb9 100644..100755
--- a/CPP/Windows/ErrorMsg.h
+++ b/CPP/Windows/ErrorMsg.h
diff --git a/CPP/Windows/FileDir.cpp b/CPP/Windows/FileDir.cpp
index 8a33fc8e..cce26385 100644..100755
--- a/CPP/Windows/FileDir.cpp
+++ b/CPP/Windows/FileDir.cpp
@@ -17,7 +17,6 @@
#include "../Common/StringConvert.h"
#include "../Common/C_FileIO.h"
-#include "TimeUtils.h"
#endif
#include "FileDir.h"
@@ -32,6 +31,30 @@ using namespace NWindows;
using namespace NFile;
using namespace NName;
+#ifndef _WIN32
+
+static bool FiTime_To_timespec(const CFiTime *ft, timespec &ts)
+{
+ if (ft)
+ {
+ ts = *ft;
+ return true;
+ }
+ // else
+ {
+ ts.tv_sec = 0;
+ ts.tv_nsec =
+ #ifdef UTIME_OMIT
+ UTIME_OMIT; // -2 keep old timesptamp
+ #else
+ // UTIME_NOW; -1 // set to the current time
+ 0;
+ #endif
+ return false;
+ }
+}
+#endif
+
namespace NWindows {
namespace NFile {
namespace NDir {
@@ -86,7 +109,7 @@ bool GetSystemDir(FString &path)
#endif // UNDER_CE
-bool SetDirTime(CFSTR path, const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime)
+bool SetDirTime(CFSTR path, const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime)
{
#ifndef _UNICODE
if (!g_IsNT)
@@ -920,39 +943,11 @@ bool GetCurrentDir(FString &path)
// #define UTIME_OMIT -2
#endif
-static bool FILETME_To_timespec(const FILETIME *ft, timespec &ts)
-{
- if (ft)
- {
- const Int64 sec = NTime::FileTimeToUnixTime64(*ft);
- // time_t is long
- const time_t sec2 = (time_t)sec;
- if (sec2 == sec)
- {
- ts.tv_sec = sec2;
- const UInt64 winTime = (((UInt64)ft->dwHighDateTime) << 32) + ft->dwLowDateTime;
- ts.tv_nsec = (long)((winTime % 10000000) * 100);
- return true;
- }
- }
- // else
- {
- ts.tv_sec = 0;
- ts.tv_nsec =
- #ifdef UTIME_OMIT
- UTIME_OMIT; // keep old timesptamp
- #else
- // UTIME_NOW; // set to the current time
- 0;
- #endif
- return false;
- }
-}
-bool SetDirTime(CFSTR path, const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime)
+bool SetDirTime(CFSTR path, const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime)
{
// need testing
/*
@@ -998,12 +993,18 @@ bool SetDirTime(CFSTR path, const FILETIME *cTime, const FILETIME *aTime, const
UNUSED_VAR(cTime)
bool needChange;
- needChange = FILETME_To_timespec(aTime, times[0]);
- needChange |= FILETME_To_timespec(mTime, times[1]);
+ needChange = FiTime_To_timespec(aTime, times[0]);
+ needChange |= FiTime_To_timespec(mTime, times[1]);
+
+ /*
+ if (mTime)
+ {
+ printf("\n time = %ld.%9ld\n", mTime->tv_sec, mTime->tv_nsec);
+ }
+ */
if (!needChange)
return true;
-
const int flags = 0; // follow link
// = AT_SYMLINK_NOFOLLOW; // don't follow link
return utimensat(AT_FDCWD, path, times, flags) == 0;
@@ -1039,6 +1040,10 @@ static C_umask g_umask;
#define TRACE_chmod(s, mode) \
PRF(printf("\n chmod(%s, %o)\n", (const char *)path, (unsigned)(mode)));
+int my_chown(CFSTR path, uid_t owner, gid_t group)
+{
+ return chown(path, owner, group);
+}
bool SetFileAttrib_PosixHighDetect(CFSTR path, DWORD attrib)
{
diff --git a/CPP/Windows/FileDir.h b/CPP/Windows/FileDir.h
index 6d6ddeaf..08281aaa 100644..100755
--- a/CPP/Windows/FileDir.h
+++ b/CPP/Windows/FileDir.h
@@ -14,7 +14,12 @@ namespace NDir {
bool GetWindowsDir(FString &path);
bool GetSystemDir(FString &path);
-bool SetDirTime(CFSTR path, const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime);
+/*
+WIN32 API : SetFileTime() doesn't allow to set zero timestamps in file
+but linux : allows unix time = 0 in filesystem
+*/
+
+bool SetDirTime(CFSTR path, const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime);
#ifdef _WIN32
@@ -27,6 +32,9 @@ bool SetFileAttrib(CFSTR path, DWORD attrib);
SetFileAttrib_PosixHighDetect() tries to detect posix field, and it extracts only attribute
bits that are related to current system only.
*/
+#else
+
+int my_chown(CFSTR path, uid_t owner, gid_t group);
#endif
diff --git a/CPP/Windows/FileFind.cpp b/CPP/Windows/FileFind.cpp
index 591f8df0..c6557599 100644..100755
--- a/CPP/Windows/FileFind.cpp
+++ b/CPP/Windows/FileFind.cpp
@@ -7,6 +7,8 @@
#ifndef _WIN32
#include <fcntl.h> /* Definition of AT_* constants */
#include "TimeUtils.h"
+// for major
+// #include <sys/sysmacros.h>
#endif
#include "FileFind.h"
@@ -62,24 +64,35 @@ bool MyGetDiskFreeSpace(CFSTR rootPath, UInt64 &clusterSize, UInt64 &totalSize,
namespace NFind {
+/*
+#ifdef _WIN32
#define MY_CLEAR_FILETIME(ft) ft.dwLowDateTime = ft.dwHighDateTime = 0;
+#else
+#define MY_CLEAR_FILETIME(ft) ft.tv_sec = 0; ft.tv_nsec = 0;
+#endif
+*/
void CFileInfoBase::ClearBase() throw()
{
Size = 0;
- MY_CLEAR_FILETIME(CTime);
- MY_CLEAR_FILETIME(ATime);
- MY_CLEAR_FILETIME(MTime);
+ FiTime_Clear(CTime);
+ FiTime_Clear(ATime);
+ FiTime_Clear(MTime);
+
+ #ifdef _WIN32
Attrib = 0;
// ReparseTag = 0;
IsAltStream = false;
IsDevice = false;
-
- #ifndef _WIN32
+ #else
+ dev = 0;
ino = 0;
- nlink = 0;
mode = 0;
- #endif
+ nlink = 0;
+ uid = 0;
+ gid = 0;
+ rdev = 0;
+ #endif
}
bool CFileInfo::IsDots() const throw()
@@ -439,6 +452,20 @@ also we support paths that are not supported by FindFirstFile:
bool CFileInfo::Find(CFSTR path, bool followLink)
{
#ifdef SUPPORT_DEVICE_FILE
+
+ if (IS_PATH_SEPAR(path[0]) &&
+ IS_PATH_SEPAR(path[1]) &&
+ path[2] == '.' &&
+ path[3] == 0)
+ {
+ // 22.00 : it's virtual directory for devices
+ // IsDevice = true;
+ ClearBase();
+ Name = path + 2;
+ Attrib = FILE_ATTRIBUTE_DIRECTORY;
+ return true;
+ }
+
if (IsDevicePath(path))
{
ClearBase();
@@ -469,7 +496,7 @@ bool CFileInfo::Find(CFSTR path, bool followLink)
#if defined(_WIN32) && !defined(UNDER_CE)
- int colonPos = FindAltStreamColon(path);
+ const int colonPos = FindAltStreamColon(path);
if (colonPos >= 0 && path[(unsigned)colonPos + 1] != 0)
{
UString streamName = fs2us(path + (unsigned)colonPos);
@@ -635,7 +662,7 @@ bool CFileInfo::Find(CFSTR path, bool followLink)
return Fill_From_ByHandleFileInfo(path);
}
-bool CFileInfo::Fill_From_ByHandleFileInfo(CFSTR path)
+bool CFileInfoBase::Fill_From_ByHandleFileInfo(CFSTR path)
{
BY_HANDLE_FILE_INFORMATION info;
if (!NIO::CFileBase::GetFileInformation(path, &info))
@@ -950,13 +977,6 @@ static const char *Get_Name_from_Path(CFSTR path) throw()
}
-void timespec_To_FILETIME(const MY_ST_TIMESPEC &ts, FILETIME &ft)
-{
- UInt64 v = NTime::UnixTime64ToFileTime64(ts.tv_sec) + ((UInt64)ts.tv_nsec / 100);
- ft.dwLowDateTime = (DWORD)v;
- ft.dwHighDateTime = (DWORD)(v >> 32);
-}
-
UInt32 Get_WinAttribPosix_From_PosixMode(UInt32 mode)
{
UInt32 attrib = S_ISDIR(mode) ?
@@ -984,7 +1004,7 @@ UInt32 Get_WinAttrib_From_stat(const struct stat &st)
void CFileInfo::SetFrom_stat(const struct stat &st)
{
- IsDevice = false;
+ // IsDevice = false;
if (S_ISDIR(st.st_mode))
{
@@ -995,7 +1015,7 @@ void CFileInfo::SetFrom_stat(const struct stat &st)
Size = (UInt64)st.st_size; // for a symbolic link, size = size of filename
}
- Attrib = Get_WinAttribPosix_From_PosixMode(st.st_mode);
+ // Attrib = Get_WinAttribPosix_From_PosixMode(st.st_mode);
// NTime::UnixTimeToFileTime(st.st_ctime, CTime);
// NTime::UnixTimeToFileTime(st.st_mtime, MTime);
@@ -1010,27 +1030,89 @@ void CFileInfo::SetFrom_stat(const struct stat &st)
*/
// timespec_To_FILETIME(st.st_birthtimespec, CTime);
// #else
- timespec_To_FILETIME(st.st_ctimespec, CTime);
+ // timespec_To_FILETIME(st.st_ctimespec, CTime);
// #endif
- timespec_To_FILETIME(st.st_mtimespec, MTime);
- timespec_To_FILETIME(st.st_atimespec, ATime);
+ // timespec_To_FILETIME(st.st_mtimespec, MTime);
+ // timespec_To_FILETIME(st.st_atimespec, ATime);
+ CTime = st.st_ctimespec;
+ MTime = st.st_mtimespec;
+ ATime = st.st_atimespec;
+
#else
- timespec_To_FILETIME(st.st_ctim, CTime);
- timespec_To_FILETIME(st.st_mtim, MTime);
- timespec_To_FILETIME(st.st_atim, ATime);
+ // timespec_To_FILETIME(st.st_ctim, CTime, &CTime_ns100);
+ // timespec_To_FILETIME(st.st_mtim, MTime, &MTime_ns100);
+ // timespec_To_FILETIME(st.st_atim, ATime, &ATime_ns100);
+ CTime = st.st_ctim;
+ MTime = st.st_mtim;
+ ATime = st.st_atim;
+
#endif
dev = st.st_dev;
ino = st.st_ino;
- nlink = st.st_nlink;
mode = st.st_mode;
+ nlink = st.st_nlink;
+ uid = st.st_uid;
+ gid = st.st_gid;
+ rdev = st.st_rdev;
+
+ /*
+ printf("\n sizeof timespec = %d", (int)sizeof(timespec));
+ printf("\n sizeof st_rdev = %d", (int)sizeof(rdev));
+ printf("\n sizeof st_ino = %d", (int)sizeof(ino));
+ printf("\n sizeof mode_t = %d", (int)sizeof(mode_t));
+ printf("\n sizeof nlink_t = %d", (int)sizeof(nlink_t));
+ printf("\n sizeof uid_t = %d", (int)sizeof(uid_t));
+ printf("\n");
+ */
+ /*
+ printf("\n st_rdev = %llx", (long long)rdev);
+ printf("\n st_dev = %llx", (long long)dev);
+ printf("\n dev : major = %5x minor = %5x", (unsigned)major(dev), (unsigned)minor(dev));
+ printf("\n st_ino = %lld", (long long)(ino));
+ printf("\n rdev : major = %5x minor = %5x", (unsigned)major(rdev), (unsigned)minor(rdev));
+ printf("\n size = %lld \n", (long long)(Size));
+ printf("\n");
+ */
+}
+
+/*
+int Uid_To_Uname(uid_t uid, AString &name)
+{
+ name.Empty();
+ struct passwd *passwd;
+
+ if (uid != 0 && uid == cached_no_such_uid)
+ {
+ *uname = xstrdup ("");
+ return;
+ }
+
+ if (!cached_uname || uid != cached_uid)
+ {
+ passwd = getpwuid (uid);
+ if (passwd)
+ {
+ cached_uid = uid;
+ assign_string (&cached_uname, passwd->pw_name);
+ }
+ else
+ {
+ cached_no_such_uid = uid;
+ *uname = xstrdup ("");
+ return;
+ }
+ }
+ *uname = xstrdup (cached_uname);
}
+*/
bool CFileInfo::Find_DontFill_Name(CFSTR path, bool followLink)
{
struct stat st;
if (MY__lstat(path, &st, followLink) != 0)
return false;
+ // printf("\nFind_DontFill_Name : name=%s\n", path);
SetFrom_stat(st);
return true;
}
@@ -1232,6 +1314,7 @@ bool CEnumerator::Fill_FileInfo(const CDirEntry &de, CFileInfo &fileInfo, bool f
if (res != 0)
return false;
+ // printf("\nname=%s\n", de.Name.Ptr());
fileInfo.SetFrom_stat(st);
fileInfo.Name = de.Name;
return true;
diff --git a/CPP/Windows/FileFind.h b/CPP/Windows/FileFind.h
index 8f28ee33..fcfe02c7 100644..100755
--- a/CPP/Windows/FileFind.h
+++ b/CPP/Windows/FileFind.h
@@ -9,10 +9,14 @@
#include <dirent.h>
#endif
+#include "../Common/MyLinux.h"
#include "../Common/MyString.h"
#include "../Common/MyWindows.h"
+
#include "Defs.h"
+#include "FileIO.h"
+
namespace NWindows {
namespace NFile {
namespace NFind {
@@ -32,6 +36,7 @@ bool DoesFileOrDirExist(CFSTR name);
DWORD GetFileAttrib(CFSTR path);
+#ifdef _WIN32
namespace NAttributes
{
@@ -42,21 +47,38 @@ namespace NAttributes
inline bool IsArchived(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_ARCHIVE) != 0; }
inline bool IsCompressed(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_COMPRESSED) != 0; }
inline bool IsEncrypted(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_ENCRYPTED) != 0; }
+
+ inline UInt32 Get_PosixMode_From_WinAttrib(DWORD attrib)
+ {
+ UInt32 v = IsDir(attrib) ? MY_LIN_S_IFDIR : MY_LIN_S_IFREG;
+ /* 21.06: as WSL we allow write permissions (0222) for directories even for (FILE_ATTRIBUTE_READONLY).
+ So extracting at Linux will be allowed to write files inside (0777) directories. */
+ v |= ((IsReadOnly(attrib) && !IsDir(attrib)) ? 0555 : 0777);
+ return v;
+ }
}
+#else
+
+UInt32 Get_WinAttribPosix_From_PosixMode(UInt32 mode);
+
+#endif
+
class CFileInfoBase
{
+ #ifdef _WIN32
bool MatchesMask(UINT32 mask) const { return ((Attrib & mask) != 0); }
+ #endif
public:
UInt64 Size;
- FILETIME CTime;
- FILETIME ATime;
- FILETIME MTime;
+ CFiTime CTime;
+ CFiTime ATime;
+ CFiTime MTime;
+ #ifdef _WIN32
DWORD Attrib;
bool IsAltStream;
bool IsDevice;
- #ifdef _WIN32
/*
#ifdef UNDER_CE
DWORD ObjectID;
@@ -64,24 +86,25 @@ public:
UINT32 ReparseTag;
#endif
*/
- #else
- dev_t dev;
+ #else
+ dev_t dev; /* ID of device containing file */
ino_t ino;
- nlink_t nlink;
mode_t mode;
+ nlink_t nlink;
+ uid_t uid; /* user ID of owner */
+ gid_t gid; /* group ID of owner */
+ dev_t rdev; /* device ID (defined, if S_ISCHR(mode) || S_ISBLK(mode)) */
// bool Use_lstat;
- #endif
+ #endif
CFileInfoBase() { ClearBase(); }
void ClearBase() throw();
-
- void SetAsDir()
- {
- Attrib = FILE_ATTRIBUTE_DIRECTORY;
- #ifndef _WIN32
- Attrib |= (FILE_ATTRIBUTE_UNIX_EXTENSION + (S_IFDIR << 16));
- #endif
- }
+
+ #ifdef _WIN32
+
+ bool Fill_From_ByHandleFileInfo(CFSTR path);
+ void SetAsDir() { Attrib = FILE_ATTRIBUTE_DIRECTORY; } // |= (FILE_ATTRIBUTE_UNIX_EXTENSION + (S_IFDIR << 16));
+ void SetAsFile() { Attrib = 0; }
bool IsArchived() const { return MatchesMask(FILE_ATTRIBUTE_ARCHIVE); }
bool IsCompressed() const { return MatchesMask(FILE_ATTRIBUTE_COMPRESSED); }
@@ -96,13 +119,33 @@ public:
bool IsSystem() const { return MatchesMask(FILE_ATTRIBUTE_SYSTEM); }
bool IsTemporary() const { return MatchesMask(FILE_ATTRIBUTE_TEMPORARY); }
- #ifndef _WIN32
- bool IsPosixLink() const
+ UInt32 GetWinAttrib() const { return Attrib; }
+ UInt32 GetPosixAttrib() const
{
- const UInt32 mod = Attrib >> 16;
- return S_ISLNK(mod);
+ return NAttributes::Get_PosixMode_From_WinAttrib(Attrib);
}
- #endif
+ bool Has_Attrib_ReparsePoint() const { return (Attrib & FILE_ATTRIBUTE_REPARSE_POINT) != 0; }
+
+ #else
+
+ UInt32 GetPosixAttrib() const { return mode; }
+ UInt32 GetWinAttrib() const { return Get_WinAttribPosix_From_PosixMode(mode); }
+
+ bool IsDir() const { return S_ISDIR(mode); }
+ void SetAsDir() { mode = S_IFDIR; }
+ void SetAsFile() { mode = S_IFREG; }
+
+ bool IsReadOnly() const
+ {
+ // does linux support writing to ReadOnly files?
+ if ((mode & 0222) == 0) // S_IWUSR in p7zip
+ return true;
+ return false;
+ }
+
+ bool IsPosixLink() const { return S_ISLNK(mode); }
+
+ #endif
bool IsOsSymLink() const
{
@@ -126,7 +169,7 @@ struct CFileInfo: public CFileInfoBase
bool Find_FollowLink(CFSTR path) { return Find(path, true); }
#ifdef _WIN32
- bool Fill_From_ByHandleFileInfo(CFSTR path);
+ // bool Fill_From_ByHandleFileInfo(CFSTR path);
// bool FollowReparse(CFSTR path, bool isDir);
#else
bool Find_DontFill_Name(CFSTR path, bool followLink = false);
@@ -287,16 +330,8 @@ inline UInt32 Get_WinAttrib_From_PosixMode(UInt32 mode)
}
*/
-UInt32 Get_WinAttribPosix_From_PosixMode(UInt32 mode);
-
// UInt32 Get_WinAttrib_From_stat(const struct stat &st);
-#if defined(_AIX)
- #define MY_ST_TIMESPEC st_timespec
-#else
- #define MY_ST_TIMESPEC timespec
-#endif
-void timespec_To_FILETIME(const MY_ST_TIMESPEC &ts, FILETIME &ft);
#endif // WIN32
diff --git a/CPP/Windows/FileIO.cpp b/CPP/Windows/FileIO.cpp
index 2974b1b7..e51b0eb3 100644..100755
--- a/CPP/Windows/FileIO.cpp
+++ b/CPP/Windows/FileIO.cpp
@@ -8,6 +8,14 @@
// #include <stdio.h>
+/*
+#ifndef _WIN32
+// for ioctl BLKGETSIZE64
+#include <sys/ioctl.h>
+#include <linux/fs.h>
+#endif
+*/
+
#include "FileIO.h"
#include "FileName.h"
@@ -615,7 +623,7 @@ namespace NWindows {
namespace NFile {
namespace NDir {
-bool SetDirTime(CFSTR path, const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime);
+bool SetDirTime(CFSTR path, const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime);
}
namespace NIO {
@@ -629,6 +637,19 @@ bool CFileBase::OpenBinary(const char *name, int flags)
Close();
_handle = ::open(name, flags, 0666);
return _handle != -1;
+
+ /*
+ if (_handle == -1)
+ return false;
+ if (IsString1PrefixedByString2(name, "/dev/"))
+ {
+ // /dev/sda
+ // IsDeviceFile = true; // for debug
+ // SizeDefined = false;
+ // SizeDefined = (GetDeviceSize_InBytes(Size) == 0);
+ }
+ return true;
+ */
}
bool CFileBase::Close()
@@ -638,6 +659,10 @@ bool CFileBase::Close()
if (close(_handle) != 0)
return false;
_handle = -1;
+ /*
+ IsDeviceFile = false;
+ SizeDefined = false;
+ */
return true;
}
@@ -651,15 +676,35 @@ bool CFileBase::GetLength(UInt64 &length) const
const off_t lengthTemp = seek(0, SEEK_END);
seek(curPos, SEEK_SET);
length = (UInt64)lengthTemp;
+
+ /*
+ // 22.00:
+ if (lengthTemp == 1)
+ if (IsDeviceFile && SizeDefined)
+ {
+ length = Size;
+ return true;
+ }
+ */
+
return (lengthTemp != -1);
}
off_t CFileBase::seek(off_t distanceToMove, int moveMethod) const
{
+ /*
+ if (IsDeviceFile && SizeDefined && moveMethod == SEEK_END)
+ {
+ printf("\n seek : IsDeviceFile moveMethod = %d distanceToMove = %ld\n", moveMethod, distanceToMove);
+ distanceToMove += Size;
+ moveMethod = SEEK_SET;
+ }
+ */
+
// printf("\nCFileBase::seek() moveMethod = %d, distanceToMove = %lld", moveMethod, (long long)distanceToMove);
// off_t res = ::lseek(_handle, distanceToMove, moveMethod);
+ // printf("\n lseek : moveMethod = %d distanceToMove = %ld\n", moveMethod, distanceToMove);
return ::lseek(_handle, distanceToMove, moveMethod);
- // printf(" res = %lld", (long long)res);
// return res;
}
@@ -694,6 +739,28 @@ bool CInFile::OpenShared(const char *name, bool)
return Open(name);
}
+
+/*
+int CFileBase::my_ioctl_BLKGETSIZE64(unsigned long long *numBlocks)
+{
+ // we can read "/sys/block/sda/size" "/sys/block/sda/sda1/size" - partition
+ // #include <linux/fs.h>
+ return ioctl(_handle, BLKGETSIZE64, numBlocks);
+ // in block size
+}
+
+int CFileBase::GetDeviceSize_InBytes(UInt64 &size)
+{
+ size = 0;
+ unsigned long long numBlocks;
+ int res = my_ioctl_BLKGETSIZE64(&numBlocks);
+ if (res == 0)
+ size = numBlocks; // another blockSize s possible?
+ printf("\nGetDeviceSize_InBytes res = %d, size = %lld\n", res, (long long)size);
+ return res;
+}
+*/
+
/*
On Linux (32-bit and 64-bit):
read(), write() (and similar system calls) will transfer at most
@@ -802,7 +869,7 @@ bool COutFile::Close()
return res;
}
-bool COutFile::SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime) throw()
+bool COutFile::SetTime(const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime) throw()
{
// On some OS (cygwin, MacOSX ...), you must close the file before updating times
// return true;
@@ -811,9 +878,22 @@ bool COutFile::SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILET
if (aTime) { ATime = *aTime; ATime_defined = true; } else ATime_defined = false;
if (mTime) { MTime = *mTime; MTime_defined = true; } else MTime_defined = false;
return true;
+
+ /*
+ struct timespec times[2];
+ UNUSED_VAR(cTime)
+ if (!aTime && !mTime)
+ return true;
+ bool needChange;
+ needChange = FiTime_To_timespec(aTime, times[0]);
+ needChange |= FiTime_To_timespec(mTime, times[1]);
+ if (!needChange)
+ return true;
+ return futimens(_handle, times) == 0;
+ */
}
-bool COutFile::SetMTime(const FILETIME *mTime) throw()
+bool COutFile::SetMTime(const CFiTime *mTime) throw()
{
if (mTime) { MTime = *mTime; MTime_defined = true; } else MTime_defined = false;
return true;
diff --git a/CPP/Windows/FileIO.h b/CPP/Windows/FileIO.h
index 22998ebe..80509653 100644..100755
--- a/CPP/Windows/FileIO.h
+++ b/CPP/Windows/FileIO.h
@@ -30,6 +30,8 @@
#include "../Common/MyString.h"
#include "../Common/MyBuffer.h"
+#include "../Windows/TimeUtils.h"
+
#include "Defs.h"
HRESULT GetLastError_noZero_HRESULT();
@@ -94,6 +96,12 @@ struct CReparseAttr
UString GetPath() const;
};
+#ifdef _WIN32
+#define CFiInfo BY_HANDLE_FILE_INFORMATION
+#define ST_MTIME(st) (st).ftLastWriteTime
+#else
+#define CFiInfo stat
+#endif
#ifdef _WIN32
@@ -142,6 +150,8 @@ public:
CFileBase(): _handle(INVALID_HANDLE_VALUE), PreserveATime(false) {};
~CFileBase() { Close(); }
+ HANDLE GetHandle() const { return _handle; }
+
bool Close() throw();
bool GetPosition(UInt64 &position) const throw();
@@ -213,6 +223,15 @@ public:
#ifndef UNDER_CE
+ bool Open_for_ReadAttributes(CFSTR fileName)
+ {
+ return Create(fileName, FILE_READ_ATTRIBUTES,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS);
+ // we must use (FILE_FLAG_BACKUP_SEMANTICS) to open handle of directory.
+ }
+
bool OpenReparse(CFSTR fileName)
{
// 17.02 fix: to support Windows XP compatibility junctions:
@@ -240,8 +259,8 @@ public:
bool Create(CFSTR fileName, bool createAlways);
bool CreateAlways(CFSTR fileName, DWORD flagsAndAttributes);
- bool SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime) throw();
- bool SetMTime(const FILETIME *mTime) throw();
+ bool SetTime(const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime) throw();
+ bool SetMTime(const CFiTime *mTime) throw();
bool WritePart(const void *data, UInt32 size, UInt32 &processedSize) throw();
bool Write(const void *data, UInt32 size, UInt32 &processedSize) throw();
bool WriteFull(const void *data, size_t size) throw();
@@ -270,6 +289,12 @@ class CFileBase
protected:
int _handle;
+ /*
+ bool IsDeviceFile;
+ bool SizeDefined;
+ UInt64 Size; // it can be larger than real available size
+ */
+
bool OpenBinary(const char *name, int flags);
public:
bool PreserveATime;
@@ -283,6 +308,11 @@ public:
off_t seekToCur() const throw();
// bool SeekToBegin() throw();
int my_fstat(struct stat *st) const { return fstat(_handle, st); }
+ /*
+ int my_ioctl_BLKGETSIZE64(unsigned long long *val);
+ int GetDeviceSize_InBytes(UInt64 &size);
+ void CalcDeviceSize(CFSTR s);
+ */
};
class CInFile: public CFileBase
@@ -301,9 +331,9 @@ class COutFile: public CFileBase
bool ATime_defined;
bool MTime_defined;
- FILETIME CTime;
- FILETIME ATime;
- FILETIME MTime;
+ CFiTime CTime;
+ CFiTime ATime;
+ CFiTime MTime;
AString Path;
ssize_t write_part(const void *data, size_t size) throw();
@@ -333,8 +363,8 @@ public:
{
return SetLength(length);
}
- bool SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime) throw();
- bool SetMTime(const FILETIME *mTime) throw();
+ bool SetTime(const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime) throw();
+ bool SetMTime(const CFiTime *mTime) throw();
};
}
diff --git a/CPP/Windows/FileLink.cpp b/CPP/Windows/FileLink.cpp
index 8ce634fd..8ce634fd 100644..100755
--- a/CPP/Windows/FileLink.cpp
+++ b/CPP/Windows/FileLink.cpp
diff --git a/CPP/Windows/FileMapping.cpp b/CPP/Windows/FileMapping.cpp
index 1933f7c8..1933f7c8 100644..100755
--- a/CPP/Windows/FileMapping.cpp
+++ b/CPP/Windows/FileMapping.cpp
diff --git a/CPP/Windows/FileMapping.h b/CPP/Windows/FileMapping.h
index f90c429f..f90c429f 100644..100755
--- a/CPP/Windows/FileMapping.h
+++ b/CPP/Windows/FileMapping.h
diff --git a/CPP/Windows/FileName.cpp b/CPP/Windows/FileName.cpp
index d61ff7e1..d61ff7e1 100644..100755
--- a/CPP/Windows/FileName.cpp
+++ b/CPP/Windows/FileName.cpp
diff --git a/CPP/Windows/FileName.h b/CPP/Windows/FileName.h
index de8bd134..de8bd134 100644..100755
--- a/CPP/Windows/FileName.h
+++ b/CPP/Windows/FileName.h
diff --git a/CPP/Windows/FileSystem.cpp b/CPP/Windows/FileSystem.cpp
index 62594532..62594532 100644..100755
--- a/CPP/Windows/FileSystem.cpp
+++ b/CPP/Windows/FileSystem.cpp
diff --git a/CPP/Windows/FileSystem.h b/CPP/Windows/FileSystem.h
index 9b49a025..9b49a025 100644..100755
--- a/CPP/Windows/FileSystem.h
+++ b/CPP/Windows/FileSystem.h
diff --git a/CPP/Windows/Handle.h b/CPP/Windows/Handle.h
index 5878c830..5878c830 100644..100755
--- a/CPP/Windows/Handle.h
+++ b/CPP/Windows/Handle.h
diff --git a/CPP/Windows/MemoryGlobal.cpp b/CPP/Windows/MemoryGlobal.cpp
index 2a22394b..2a22394b 100644..100755
--- a/CPP/Windows/MemoryGlobal.cpp
+++ b/CPP/Windows/MemoryGlobal.cpp
diff --git a/CPP/Windows/MemoryGlobal.h b/CPP/Windows/MemoryGlobal.h
index c217510e..c217510e 100644..100755
--- a/CPP/Windows/MemoryGlobal.h
+++ b/CPP/Windows/MemoryGlobal.h
diff --git a/CPP/Windows/MemoryLock.cpp b/CPP/Windows/MemoryLock.cpp
index fdfbeb9d..fdfbeb9d 100644..100755
--- a/CPP/Windows/MemoryLock.cpp
+++ b/CPP/Windows/MemoryLock.cpp
diff --git a/CPP/Windows/MemoryLock.h b/CPP/Windows/MemoryLock.h
index dcaf182e..dcaf182e 100644..100755
--- a/CPP/Windows/MemoryLock.h
+++ b/CPP/Windows/MemoryLock.h
diff --git a/CPP/Windows/Menu.cpp b/CPP/Windows/Menu.cpp
index 3ad69530..3ad69530 100644..100755
--- a/CPP/Windows/Menu.cpp
+++ b/CPP/Windows/Menu.cpp
diff --git a/CPP/Windows/Menu.h b/CPP/Windows/Menu.h
index aacdc7c3..aacdc7c3 100644..100755
--- a/CPP/Windows/Menu.h
+++ b/CPP/Windows/Menu.h
diff --git a/CPP/Windows/NationalTime.cpp b/CPP/Windows/NationalTime.cpp
index 0dcd31e0..0dcd31e0 100644..100755
--- a/CPP/Windows/NationalTime.cpp
+++ b/CPP/Windows/NationalTime.cpp
diff --git a/CPP/Windows/NationalTime.h b/CPP/Windows/NationalTime.h
index 49b0e5e8..49b0e5e8 100644..100755
--- a/CPP/Windows/NationalTime.h
+++ b/CPP/Windows/NationalTime.h
diff --git a/CPP/Windows/Net.cpp b/CPP/Windows/Net.cpp
index 2a3952a1..2a3952a1 100644..100755
--- a/CPP/Windows/Net.cpp
+++ b/CPP/Windows/Net.cpp
diff --git a/CPP/Windows/Net.h b/CPP/Windows/Net.h
index 7b60b1b4..7b60b1b4 100644..100755
--- a/CPP/Windows/Net.h
+++ b/CPP/Windows/Net.h
diff --git a/CPP/Windows/NtCheck.h b/CPP/Windows/NtCheck.h
index 0af32911..0af32911 100644..100755
--- a/CPP/Windows/NtCheck.h
+++ b/CPP/Windows/NtCheck.h
diff --git a/CPP/Windows/ProcessMessages.cpp b/CPP/Windows/ProcessMessages.cpp
index 0f48aee2..0f48aee2 100644..100755
--- a/CPP/Windows/ProcessMessages.cpp
+++ b/CPP/Windows/ProcessMessages.cpp
diff --git a/CPP/Windows/ProcessMessages.h b/CPP/Windows/ProcessMessages.h
index b2558a01..b2558a01 100644..100755
--- a/CPP/Windows/ProcessMessages.h
+++ b/CPP/Windows/ProcessMessages.h
diff --git a/CPP/Windows/ProcessUtils.cpp b/CPP/Windows/ProcessUtils.cpp
index 9bf05383..9bf05383 100644..100755
--- a/CPP/Windows/ProcessUtils.cpp
+++ b/CPP/Windows/ProcessUtils.cpp
diff --git a/CPP/Windows/ProcessUtils.h b/CPP/Windows/ProcessUtils.h
index e46f9ab2..e46f9ab2 100644..100755
--- a/CPP/Windows/ProcessUtils.h
+++ b/CPP/Windows/ProcessUtils.h
diff --git a/CPP/Windows/PropVariant.cpp b/CPP/Windows/PropVariant.cpp
index 6e43c7bc..2b179500 100644..100755
--- a/CPP/Windows/PropVariant.cpp
+++ b/CPP/Windows/PropVariant.cpp
@@ -193,7 +193,7 @@ BSTR CPropVariant::AllocBstr(unsigned numChars)
}
#define SET_PROP_id_dest(id, dest) \
- if (vt != id) { InternalClear(); vt = id; } dest = value;
+ if (vt != id) { InternalClear(); vt = id; } dest = value; wReserved1 = 0;
void CPropVariant::Set_Int32(Int32 value) throw()
{
@@ -217,67 +217,83 @@ SET_PROP_FUNC(UInt64, VT_UI8, uhVal.QuadPart)
// SET_PROP_FUNC(Int64, VT_I8, hVal.QuadPart)
SET_PROP_FUNC(const FILETIME &, VT_FILETIME, filetime)
+#define CASE_SIMPLE_VT_VALUES \
+ case VT_EMPTY: \
+ case VT_BOOL: \
+ case VT_FILETIME: \
+ case VT_UI8: \
+ case VT_UI4: \
+ case VT_UI2: \
+ case VT_UI1: \
+ case VT_I8: \
+ case VT_I4: \
+ case VT_I2: \
+ case VT_I1: \
+ case VT_UINT: \
+ case VT_INT: \
+ case VT_NULL: \
+ case VT_ERROR: \
+ case VT_R4: \
+ case VT_R8: \
+ case VT_CY: \
+ case VT_DATE: \
+
+
+/*
+ ::VariantClear() and ::VariantCopy() don't work, if (vt == VT_FILETIME)
+ So we handle VT_FILETIME and another simple types directly
+ we call system functions for VT_BSTR and for unknown typed
+*/
+
+CPropVariant::~CPropVariant()
+{
+ switch ((unsigned)vt)
+ {
+ CASE_SIMPLE_VT_VALUES
+ // vt = VT_EMPTY; // it's optional
+ return;
+ }
+ ::VariantClear((tagVARIANT *)this);
+}
+
HRESULT PropVariant_Clear(PROPVARIANT *prop) throw()
{
- switch (prop->vt)
+ switch ((unsigned)prop->vt)
{
- case VT_EMPTY:
- case VT_UI1:
- case VT_I1:
- case VT_I2:
- case VT_UI2:
- case VT_BOOL:
- case VT_I4:
- case VT_UI4:
- case VT_R4:
- case VT_INT:
- case VT_UINT:
- case VT_ERROR:
- case VT_FILETIME:
- case VT_UI8:
- case VT_R8:
- case VT_CY:
- case VT_DATE:
+ CASE_SIMPLE_VT_VALUES
prop->vt = VT_EMPTY;
- prop->wReserved1 = 0;
- prop->wReserved2 = 0;
- prop->wReserved3 = 0;
- prop->uhVal.QuadPart = 0;
- return S_OK;
+ break;
+ default:
+ {
+ const HRESULT res = ::VariantClear((VARIANTARG *)prop);
+ if (res != S_OK || prop->vt != VT_EMPTY)
+ return res;
+ break;
+ }
}
- return ::VariantClear((VARIANTARG *)prop);
- // return ::PropVariantClear(prop);
- // PropVariantClear can clear VT_BLOB.
+ prop->wReserved1 = 0;
+ prop->wReserved2 = 0;
+ prop->wReserved3 = 0;
+ prop->uhVal.QuadPart = 0;
+ return S_OK;
}
HRESULT CPropVariant::Clear() throw()
{
if (vt == VT_EMPTY)
+ {
+ wReserved1 = 0;
return S_OK;
+ }
return PropVariant_Clear(this);
}
HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc) throw()
{
- ::VariantClear((tagVARIANT *)this);
- switch (pSrc->vt)
+ Clear();
+ switch ((unsigned)pSrc->vt)
{
- case VT_UI1:
- case VT_I1:
- case VT_I2:
- case VT_UI2:
- case VT_BOOL:
- case VT_I4:
- case VT_UI4:
- case VT_R4:
- case VT_INT:
- case VT_UINT:
- case VT_ERROR:
- case VT_FILETIME:
- case VT_UI8:
- case VT_R8:
- case VT_CY:
- case VT_DATE:
+ CASE_SIMPLE_VT_VALUES
memmove((PROPVARIANT*)this, pSrc, sizeof(PROPVARIANT));
return S_OK;
}
@@ -287,12 +303,13 @@ HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc) throw()
HRESULT CPropVariant::Attach(PROPVARIANT *pSrc) throw()
{
- HRESULT hr = Clear();
+ const HRESULT hr = Clear();
if (FAILED(hr))
return hr;
// memcpy((PROPVARIANT *)this, pSrc, sizeof(PROPVARIANT));
*(PROPVARIANT *)this = *pSrc;
pSrc->vt = VT_EMPTY;
+ pSrc->wReserved1 = 0;
return S_OK;
}
@@ -300,21 +317,25 @@ HRESULT CPropVariant::Detach(PROPVARIANT *pDest) throw()
{
if (pDest->vt != VT_EMPTY)
{
- HRESULT hr = PropVariant_Clear(pDest);
+ const HRESULT hr = PropVariant_Clear(pDest);
if (FAILED(hr))
return hr;
}
// memcpy(pDest, this, sizeof(PROPVARIANT));
*pDest = *(PROPVARIANT *)this;
vt = VT_EMPTY;
+ wReserved1 = 0;
return S_OK;
}
HRESULT CPropVariant::InternalClear() throw()
{
if (vt == VT_EMPTY)
+ {
+ wReserved1 = 0;
return S_OK;
- HRESULT hr = Clear();
+ }
+ const HRESULT hr = Clear();
if (FAILED(hr))
{
vt = VT_ERROR;
@@ -325,7 +346,7 @@ HRESULT CPropVariant::InternalClear() throw()
void CPropVariant::InternalCopy(const PROPVARIANT *pSrc)
{
- HRESULT hr = Copy(pSrc);
+ const HRESULT hr = Copy(pSrc);
if (FAILED(hr))
{
if (hr == E_OUTOFMEMORY)
@@ -335,11 +356,12 @@ void CPropVariant::InternalCopy(const PROPVARIANT *pSrc)
}
}
+
int CPropVariant::Compare(const CPropVariant &a) throw()
{
if (vt != a.vt)
return MyCompare(vt, a.vt);
- switch (vt)
+ switch ((unsigned)vt)
{
case VT_EMPTY: return 0;
// case VT_I1: return MyCompare(cVal, a.cVal);
@@ -352,7 +374,15 @@ int CPropVariant::Compare(const CPropVariant &a) throw()
case VT_I8: return MyCompare(hVal.QuadPart, a.hVal.QuadPart);
case VT_UI8: return MyCompare(uhVal.QuadPart, a.uhVal.QuadPart);
case VT_BOOL: return -MyCompare(boolVal, a.boolVal);
- case VT_FILETIME: return ::CompareFileTime(&filetime, &a.filetime);
+ case VT_FILETIME:
+ {
+ const int res = CompareFileTime(&filetime, &a.filetime);
+ if (res != 0)
+ return res;
+ const unsigned v1 = Get_Ns100();
+ const unsigned v2 = a.Get_Ns100();
+ return MyCompare(v1, v2);
+ }
case VT_BSTR: return 0; // Not implemented
default: return 0;
}
diff --git a/CPP/Windows/PropVariant.h b/CPP/Windows/PropVariant.h
index 108bf6b9..171402f7 100644..100755
--- a/CPP/Windows/PropVariant.h
+++ b/CPP/Windows/PropVariant.h
@@ -29,11 +29,14 @@ inline void PropVarEm_Set_UInt64(PROPVARIANT *p, UInt64 v) throw()
p->uhVal.QuadPart = v;
}
-inline void PropVarEm_Set_FileTime64(PROPVARIANT *p, UInt64 v) throw()
+inline void PropVarEm_Set_FileTime64_Prec(PROPVARIANT *p, UInt64 v, unsigned prec) throw()
{
p->vt = VT_FILETIME;
p->filetime.dwLowDateTime = (DWORD)v;
p->filetime.dwHighDateTime = (DWORD)(v >> 32);
+ p->wReserved1 = (WORD)prec;
+ p->wReserved2 = 0;
+ p->wReserved3 = 0;
}
inline void PropVarEm_Set_Bool(PROPVARIANT *p, bool b) throw()
@@ -63,7 +66,51 @@ public:
// uhVal.QuadPart = 0;
bstrVal = 0;
}
- ~CPropVariant() throw() { Clear(); }
+
+
+ void Set_FtPrec(unsigned prec)
+ {
+ wReserved1 = (WORD)prec;
+ wReserved2 = 0;
+ wReserved3 = 0;
+ }
+
+ void SetAsTimeFrom_FT_Prec(const FILETIME &ft, unsigned prec)
+ {
+ operator=(ft);
+ Set_FtPrec(prec);
+ }
+
+ void SetAsTimeFrom_Ft64_Prec(UInt64 v, unsigned prec)
+ {
+ FILETIME ft;
+ ft.dwLowDateTime = (DWORD)(UInt32)v;
+ ft.dwHighDateTime = (DWORD)(UInt32)(v >> 32);
+ operator=(ft);
+ Set_FtPrec(prec);
+ }
+
+ void SetAsTimeFrom_FT_Prec_Ns100(const FILETIME &ft, unsigned prec, unsigned ns100)
+ {
+ operator=(ft);
+ wReserved1 = (WORD)prec;
+ wReserved2 = (WORD)ns100;
+ wReserved3 = 0;
+ }
+
+ unsigned Get_Ns100() const
+ {
+ const unsigned prec = wReserved1;
+ const unsigned ns100 = wReserved2;
+ if (prec == 0
+ && prec <= k_PropVar_TimePrec_1ns
+ && ns100 < 100
+ && wReserved3 == 0)
+ return ns100;
+ return 0;
+ }
+
+ ~CPropVariant();
CPropVariant(const PROPVARIANT &varSrc);
CPropVariant(const CPropVariant &varSrc);
CPropVariant(BSTR bstrSrc);
@@ -118,7 +165,6 @@ public:
HRESULT InternalClear() throw();
void InternalCopy(const PROPVARIANT *pSrc);
-
int Compare(const CPropVariant &a) throw();
};
diff --git a/CPP/Windows/PropVariantConv.cpp b/CPP/Windows/PropVariantConv.cpp
index b58d37e6..3c9bbd17 100644..100755
--- a/CPP/Windows/PropVariantConv.cpp
+++ b/CPP/Windows/PropVariantConv.cpp
@@ -9,7 +9,7 @@
#define UINT_TO_STR_2(c, val) { s[0] = (c); s[1] = (char)('0' + (val) / 10); s[2] = (char)('0' + (val) % 10); s += 3; }
-bool ConvertUtcFileTimeToString(const FILETIME &utc, char *s, int level) throw()
+bool ConvertUtcFileTimeToString2(const FILETIME &utc, unsigned ns100, char *s, int level) throw()
{
*s = 0;
FILETIME ft;
@@ -18,7 +18,10 @@ bool ConvertUtcFileTimeToString(const FILETIME &utc, char *s, int level) throw()
SYSTEMTIME st;
if (!BOOLToBool(FileTimeToSystemTime(&ft, &st)))
+ {
+ // win10 : that function doesn't work, if bit 63 of 64-bit FILETIME is set.
return false;
+ }
{
unsigned val = st.wYear;
@@ -71,6 +74,12 @@ bool ConvertUtcFileTimeToString(const FILETIME &utc, char *s, int level) throw()
numDigits = (unsigned)level;
s += numDigits;
}
+ if (level >= kTimestampPrintLevel_NTFS + 1)
+ {
+ *s++ = (char)('0' + (ns100 / 10));
+ if (level >= kTimestampPrintLevel_NTFS + 2)
+ *s++ = (char)('0' + (ns100 % 10));
+ }
}
}
}
@@ -80,6 +89,25 @@ bool ConvertUtcFileTimeToString(const FILETIME &utc, char *s, int level) throw()
}
+bool ConvertUtcFileTimeToString(const FILETIME &utc, char *s, int level) throw()
+{
+ return ConvertUtcFileTimeToString2(utc, 0, s, level);
+}
+
+bool ConvertUtcFileTimeToString2(const FILETIME &ft, unsigned ns100, wchar_t *dest, int level) throw()
+{
+ char s[32];
+ bool res = ConvertUtcFileTimeToString2(ft, ns100, s, level);
+ for (unsigned i = 0;; i++)
+ {
+ Byte c = (Byte)s[i];
+ dest[i] = c;
+ if (c == 0)
+ break;
+ }
+ return res;
+}
+
bool ConvertUtcFileTimeToString(const FILETIME &ft, wchar_t *dest, int level) throw()
{
char s[32];
@@ -106,7 +134,19 @@ void ConvertPropVariantToShortString(const PROPVARIANT &prop, char *dest) throw(
case VT_UI2: ConvertUInt32ToString(prop.uiVal, dest); return;
case VT_UI4: ConvertUInt32ToString(prop.ulVal, dest); return;
case VT_UI8: ConvertUInt64ToString(prop.uhVal.QuadPart, dest); return;
- case VT_FILETIME: ConvertUtcFileTimeToString(prop.filetime, dest); return;
+ case VT_FILETIME:
+ {
+ // const unsigned prec = prop.wReserved1;
+ int level = 0;
+ /*
+ if (prec == 0)
+ level = 7;
+ else if (prec > 16 && prec <= 16 + 9)
+ level = prec - 16;
+ */
+ ConvertUtcFileTimeToString(prop.filetime, dest, level);
+ return;
+ }
// case VT_I1: return ConvertInt64ToString(prop.cVal, dest); return;
case VT_I2: ConvertInt64ToString(prop.iVal, dest); return;
case VT_I4: ConvertInt64ToString(prop.lVal, dest); return;
@@ -127,7 +167,19 @@ void ConvertPropVariantToShortString(const PROPVARIANT &prop, wchar_t *dest) thr
case VT_UI2: ConvertUInt32ToString(prop.uiVal, dest); return;
case VT_UI4: ConvertUInt32ToString(prop.ulVal, dest); return;
case VT_UI8: ConvertUInt64ToString(prop.uhVal.QuadPart, dest); return;
- case VT_FILETIME: ConvertUtcFileTimeToString(prop.filetime, dest); return;
+ case VT_FILETIME:
+ {
+ // const unsigned prec = prop.wReserved1;
+ int level = 0;
+ /*
+ if (prec == 0)
+ level = 7;
+ else if (prec > 16 && prec <= 16 + 9)
+ level = prec - 16;
+ */
+ ConvertUtcFileTimeToString(prop.filetime, dest, level);
+ return;
+ }
// case VT_I1: return ConvertInt64ToString(prop.cVal, dest); return;
case VT_I2: ConvertInt64ToString(prop.iVal, dest); return;
case VT_I4: ConvertInt64ToString(prop.lVal, dest); return;
diff --git a/CPP/Windows/PropVariantConv.h b/CPP/Windows/PropVariantConv.h
index 390e0b89..60677840 100644..100755
--- a/CPP/Windows/PropVariantConv.h
+++ b/CPP/Windows/PropVariantConv.h
@@ -10,11 +10,14 @@
#define kTimestampPrintLevel_DAY -3
// #define kTimestampPrintLevel_HOUR -2
#define kTimestampPrintLevel_MIN -1
-#define kTimestampPrintLevel_SEC 0
+#define kTimestampPrintLevel_SEC 0
#define kTimestampPrintLevel_NTFS 7
+#define kTimestampPrintLevel_NS 9
bool ConvertUtcFileTimeToString(const FILETIME &ft, char *s, int level = kTimestampPrintLevel_SEC) throw();
bool ConvertUtcFileTimeToString(const FILETIME &ft, wchar_t *s, int level = kTimestampPrintLevel_SEC) throw();
+bool ConvertUtcFileTimeToString2(const FILETIME &ft, unsigned ns100, char *s, int level = kTimestampPrintLevel_SEC) throw();
+bool ConvertUtcFileTimeToString2(const FILETIME &ft, unsigned ns100, wchar_t *s, int level = kTimestampPrintLevel_SEC) throw();
// provide at least 32 bytes for buffer including zero-end
// don't send VT_BSTR to these functions
diff --git a/CPP/Windows/PropVariantUtils.cpp b/CPP/Windows/PropVariantUtils.cpp
index 6daee839..6daee839 100644..100755
--- a/CPP/Windows/PropVariantUtils.cpp
+++ b/CPP/Windows/PropVariantUtils.cpp
diff --git a/CPP/Windows/PropVariantUtils.h b/CPP/Windows/PropVariantUtils.h
index 3dd8295f..3dd8295f 100644..100755
--- a/CPP/Windows/PropVariantUtils.h
+++ b/CPP/Windows/PropVariantUtils.h
diff --git a/CPP/Windows/Registry.cpp b/CPP/Windows/Registry.cpp
index b20157d5..b20157d5 100644..100755
--- a/CPP/Windows/Registry.cpp
+++ b/CPP/Windows/Registry.cpp
diff --git a/CPP/Windows/Registry.h b/CPP/Windows/Registry.h
index ca79dfe3..ca79dfe3 100644..100755
--- a/CPP/Windows/Registry.h
+++ b/CPP/Windows/Registry.h
diff --git a/CPP/Windows/ResourceString.cpp b/CPP/Windows/ResourceString.cpp
index ae8182ed..ae8182ed 100644..100755
--- a/CPP/Windows/ResourceString.cpp
+++ b/CPP/Windows/ResourceString.cpp
diff --git a/CPP/Windows/ResourceString.h b/CPP/Windows/ResourceString.h
index f0bdabf4..f0bdabf4 100644..100755
--- a/CPP/Windows/ResourceString.h
+++ b/CPP/Windows/ResourceString.h
diff --git a/CPP/Windows/SecurityUtils.cpp b/CPP/Windows/SecurityUtils.cpp
index 640c90dc..8a7f45cd 100644..100755
--- a/CPP/Windows/SecurityUtils.cpp
+++ b/CPP/Windows/SecurityUtils.cpp
@@ -2,8 +2,6 @@
#include "StdAfx.h"
-#include "../Common/MyString.h"
-
#include "SecurityUtils.h"
namespace NWindows {
diff --git a/CPP/Windows/SecurityUtils.h b/CPP/Windows/SecurityUtils.h
index 8966dfd3..8966dfd3 100644..100755
--- a/CPP/Windows/SecurityUtils.h
+++ b/CPP/Windows/SecurityUtils.h
diff --git a/CPP/Windows/Shell.cpp b/CPP/Windows/Shell.cpp
index d0f9032c..d0f9032c 100644..100755
--- a/CPP/Windows/Shell.cpp
+++ b/CPP/Windows/Shell.cpp
diff --git a/CPP/Windows/Shell.h b/CPP/Windows/Shell.h
index de91d3f1..de91d3f1 100644..100755
--- a/CPP/Windows/Shell.h
+++ b/CPP/Windows/Shell.h
diff --git a/CPP/Windows/StdAfx.h b/CPP/Windows/StdAfx.h
index 1766dfa8..1766dfa8 100644..100755
--- a/CPP/Windows/StdAfx.h
+++ b/CPP/Windows/StdAfx.h
diff --git a/CPP/Windows/Synchronization.cpp b/CPP/Windows/Synchronization.cpp
index fbf919dc..fbf919dc 100644..100755
--- a/CPP/Windows/Synchronization.cpp
+++ b/CPP/Windows/Synchronization.cpp
diff --git a/CPP/Windows/Synchronization.h b/CPP/Windows/Synchronization.h
index 7d2e8d2a..7d2e8d2a 100644..100755
--- a/CPP/Windows/Synchronization.h
+++ b/CPP/Windows/Synchronization.h
diff --git a/CPP/Windows/System.cpp b/CPP/Windows/System.cpp
index 3a14b77d..3a14b77d 100644..100755
--- a/CPP/Windows/System.cpp
+++ b/CPP/Windows/System.cpp
diff --git a/CPP/Windows/System.h b/CPP/Windows/System.h
index 23cb0dab..23cb0dab 100644..100755
--- a/CPP/Windows/System.h
+++ b/CPP/Windows/System.h
diff --git a/CPP/Windows/SystemInfo.cpp b/CPP/Windows/SystemInfo.cpp
index d882a8ee..d882a8ee 100644..100755
--- a/CPP/Windows/SystemInfo.cpp
+++ b/CPP/Windows/SystemInfo.cpp
diff --git a/CPP/Windows/SystemInfo.h b/CPP/Windows/SystemInfo.h
index e941d0aa..e941d0aa 100644..100755
--- a/CPP/Windows/SystemInfo.h
+++ b/CPP/Windows/SystemInfo.h
diff --git a/CPP/Windows/Thread.h b/CPP/Windows/Thread.h
index 5fca173f..5fca173f 100644..100755
--- a/CPP/Windows/Thread.h
+++ b/CPP/Windows/Thread.h
diff --git a/CPP/Windows/TimeUtils.cpp b/CPP/Windows/TimeUtils.cpp
index 1f1335f9..77d2c510 100644..100755
--- a/CPP/Windows/TimeUtils.cpp
+++ b/CPP/Windows/TimeUtils.cpp
@@ -22,7 +22,7 @@ static const UInt64 kUnixTimeOffset =
(UInt64)60 * 60 * 24 * (89 + 365 * (kUnixTimeStartYear - kFileTimeStartYear));
static const UInt64 kNumSecondsInFileTime = (UInt64)(Int64)-1 / kNumTimeQuantumsInSecond;
-bool DosTimeToFileTime(UInt32 dosTime, FILETIME &ft) throw()
+bool DosTime_To_FileTime(UInt32 dosTime, FILETIME &ft) throw()
{
#if defined(_WIN32) && !defined(UNDER_CE)
return BOOLToBool(::DosDateTimeToFileTime((UInt16)(dosTime >> 16), (UInt16)(dosTime & 0xFFFF), &ft));
@@ -43,7 +43,7 @@ bool DosTimeToFileTime(UInt32 dosTime, FILETIME &ft) throw()
static const UInt32 kHighDosTime = 0xFF9FBF7D;
static const UInt32 kLowDosTime = 0x210000;
-bool FileTimeToDosTime(const FILETIME &ft, UInt32 &dosTime) throw()
+bool FileTime_To_DosTime(const FILETIME &ft, UInt32 &dosTime) throw()
{
#if defined(_WIN32) && !defined(UNDER_CE)
@@ -121,49 +121,86 @@ bool FileTimeToDosTime(const FILETIME &ft, UInt32 &dosTime) throw()
return true;
}
-UInt64 UnixTimeToFileTime64(UInt32 unixTime) throw()
+
+bool UtcFileTime_To_LocalDosTime(const FILETIME &utc, UInt32 &dosTime) throw()
+{
+ FILETIME loc = { 0, 0 };
+ const UInt64 u1 = FILETIME_To_UInt64(utc);
+ const UInt64 kDelta = ((UInt64)1 << 41); // it's larger than quantums in 1 sec.
+ if (u1 >= kDelta)
+ {
+ if (!FileTimeToLocalFileTime(&utc, &loc))
+ loc = utc;
+ else
+ {
+ const UInt64 u2 = FILETIME_To_UInt64(loc);
+ const UInt64 delta = u1 < u2 ? (u2 - u1) : (u1 - u2);
+ if (delta > kDelta) // if FileTimeToLocalFileTime() overflow, we use UTC time
+ loc = utc;
+ }
+ }
+ return FileTime_To_DosTime(loc, dosTime);
+}
+
+UInt64 UnixTime_To_FileTime64(UInt32 unixTime) throw()
{
return (kUnixTimeOffset + (UInt64)unixTime) * kNumTimeQuantumsInSecond;
}
-void UnixTimeToFileTime(UInt32 unixTime, FILETIME &ft) throw()
+void UnixTime_To_FileTime(UInt32 unixTime, FILETIME &ft) throw()
{
- UInt64 v = UnixTimeToFileTime64(unixTime);
+ const UInt64 v = UnixTime_To_FileTime64(unixTime);
ft.dwLowDateTime = (DWORD)v;
ft.dwHighDateTime = (DWORD)(v >> 32);
}
-UInt64 UnixTime64ToFileTime64(Int64 unixTime) throw()
+UInt64 UnixTime64_To_FileTime64(Int64 unixTime) throw()
{
return (UInt64)((Int64)kUnixTimeOffset + unixTime) * kNumTimeQuantumsInSecond;
}
-bool UnixTime64ToFileTime(Int64 unixTime, FILETIME &ft) throw()
+
+bool UnixTime64_To_FileTime64(Int64 unixTime, UInt64 &fileTime) throw()
{
if (unixTime > (Int64)(kNumSecondsInFileTime - kUnixTimeOffset))
{
- ft.dwLowDateTime = ft.dwHighDateTime = (UInt32)(Int32)-1;
+ fileTime = (UInt64)(Int64)-1;
return false;
}
- Int64 v = (Int64)kUnixTimeOffset + unixTime;
- if (v < 0)
+ if (unixTime < -(Int64)kUnixTimeOffset)
{
- ft.dwLowDateTime = ft.dwHighDateTime = 0;
+ fileTime = 0;
return false;
}
- UInt64 v2 = (UInt64)v * kNumTimeQuantumsInSecond;
- ft.dwLowDateTime = (DWORD)v2;
- ft.dwHighDateTime = (DWORD)(v2 >> 32);
+ fileTime = UnixTime64_To_FileTime64(unixTime);
return true;
}
-Int64 FileTimeToUnixTime64(const FILETIME &ft) throw()
+
+bool UnixTime64_To_FileTime(Int64 unixTime, FILETIME &ft) throw()
{
- UInt64 winTime = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
+ UInt64 v;
+ const bool res = UnixTime64_To_FileTime64(unixTime, v);
+ ft.dwLowDateTime = (DWORD)v;
+ ft.dwHighDateTime = (DWORD)(v >> 32);
+ return res;
+}
+
+
+Int64 FileTime_To_UnixTime64(const FILETIME &ft) throw()
+{
+ const UInt64 winTime = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
+ return (Int64)(winTime / kNumTimeQuantumsInSecond) - (Int64)kUnixTimeOffset;
+}
+
+Int64 FileTime_To_UnixTime64_and_Quantums(const FILETIME &ft, UInt32 &quantums) throw()
+{
+ const UInt64 winTime = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
+ quantums = (UInt32)(winTime % kNumTimeQuantumsInSecond);
return (Int64)(winTime / kNumTimeQuantumsInSecond) - (Int64)kUnixTimeOffset;
}
-bool FileTimeToUnixTime(const FILETIME &ft, UInt32 &unixTime) throw()
+bool FileTime_To_UnixTime(const FILETIME &ft, UInt32 &unixTime) throw()
{
UInt64 winTime = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
winTime /= kNumTimeQuantumsInSecond;
@@ -173,9 +210,9 @@ bool FileTimeToUnixTime(const FILETIME &ft, UInt32 &unixTime) throw()
return false;
}
winTime -= kUnixTimeOffset;
- if (winTime > 0xFFFFFFFF)
+ if (winTime > (UInt32)0xFFFFFFFF)
{
- unixTime = 0xFFFFFFFF;
+ unixTime = (UInt32)0xFFFFFFFF;
return false;
}
unixTime = (UInt32)winTime;
@@ -202,12 +239,13 @@ bool GetSecondsSince1601(unsigned year, unsigned month, unsigned day,
return true;
}
-void GetCurUtcFileTime(FILETIME &ft) throw()
+
+void GetCurUtc_FiTime(CFiTime &ft) throw()
{
+ #ifdef _WIN32
+
// Both variants provide same low resolution on WinXP: about 15 ms.
// But GetSystemTimeAsFileTime is much faster.
- #ifdef _WIN32
-
#ifdef UNDER_CE
SYSTEMTIME st;
GetSystemTime(&st);
@@ -216,8 +254,22 @@ void GetCurUtcFileTime(FILETIME &ft) throw()
GetSystemTimeAsFileTime(&ft);
#endif
- #else
+ #else
+ FiTime_Clear(ft);
+ struct timeval now;
+ if (gettimeofday(&now, 0 ) == 0)
+ {
+ ft.tv_sec = now.tv_sec;
+ ft.tv_nsec = now.tv_usec * 1000;
+ }
+
+ #endif
+}
+
+#ifndef _WIN32
+void GetCurUtcFileTime(FILETIME &ft) throw()
+{
UInt64 v = 0;
struct timeval now;
if (gettimeofday(&now, 0 ) == 0)
@@ -227,8 +279,126 @@ void GetCurUtcFileTime(FILETIME &ft) throw()
}
ft.dwLowDateTime = (DWORD)v;
ft.dwHighDateTime = (DWORD)(v >> 32);
-
- #endif
}
+#endif
+
}}
+
+
+#ifdef _WIN32
+
+/*
+void FiTime_Normalize_With_Prec(CFiTime &ft, unsigned prec)
+{
+ if (prec == k_PropVar_TimePrec_0
+ || prec == k_PropVar_TimePrec_HighPrec
+ || prec >= k_PropVar_TimePrec_100ns)
+ return;
+ UInt64 v = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
+
+ int numDigits = (int)prec - (int)k_PropVar_TimePrec_Base;
+ UInt32 d;
+ if (prec == k_PropVar_TimePrec_DOS)
+ {
+ // we round up as windows DosDateTimeToFileTime()
+ v += NWindows::NTime::kNumTimeQuantumsInSecond * 2 - 1;
+ d = NWindows::NTime::kNumTimeQuantumsInSecond * 2;
+ }
+ else
+ {
+ if (prec == k_PropVar_TimePrec_Unix)
+ numDigits = 0;
+ else if (numDigits < 0)
+ return;
+ d = 1;
+ for (unsigned k = numDigits; k < 7; k++)
+ d *= 10;
+ }
+ v /= d;
+ v *= d;
+ ft.dwLowDateTime = (DWORD)v;
+ ft.dwHighDateTime = (DWORD)(v >> 32);
+}
+*/
+
+#else
+
+/*
+void FiTime_Normalize_With_Prec(CFiTime &ft, unsigned prec)
+{
+ if (prec >= k_PropVar_TimePrec_1ns
+ || prec == k_PropVar_TimePrec_HighPrec)
+ return;
+
+ int numDigits = (int)prec - (int)k_PropVar_TimePrec_Base;
+ UInt32 d;
+ if (prec == k_PropVar_TimePrec_Unix ||
+ prec == (int)k_PropVar_TimePrec_Base)
+ {
+ ft.tv_nsec = 0;
+ return;
+ }
+ if (prec == k_PropVar_TimePrec_DOS)
+ {
+ // we round up as windows DosDateTimeToFileTime()
+ const unsigned sec1 = (ft.tv_sec & 1);
+ if (ft.tv_nsec == 0 && sec1 == 0)
+ return;
+ ft.tv_nsec = 0;
+ ft.tv_sec += 2 - sec1;
+ return;
+ }
+ {
+ if (prec == k_PropVar_TimePrec_0
+ || numDigits < 0)
+ numDigits = 7;
+ d = 1;
+ for (unsigned k = numDigits; k < 9; k++)
+ d *= 10;
+ ft.tv_nsec /= d;
+ ft.tv_nsec *= d;
+ }
+}
+*/
+
+int Compare_FiTime(const CFiTime *a1, const CFiTime *a2)
+{
+ if (a1->tv_sec < a2->tv_sec) return -1;
+ if (a1->tv_sec > a2->tv_sec) return 1;
+ if (a1->tv_nsec < a2->tv_nsec) return -1;
+ if (a1->tv_nsec > a2->tv_nsec) return 1;
+ return 0;
+}
+
+bool FILETIME_To_timespec(const FILETIME &ft, timespec &ts)
+{
+ UInt32 quantums;
+ const Int64 sec = NWindows::NTime::FileTime_To_UnixTime64_and_Quantums(ft, quantums);
+ // time_t is long
+ const time_t sec2 = (time_t)sec;
+ if (sec2 == sec)
+ {
+ ts.tv_sec = sec2;
+ ts.tv_nsec = (long)(quantums * 100);
+ return true;
+ }
+ return false;
+}
+
+void FiTime_To_FILETIME_ns100(const CFiTime &ts, FILETIME &ft, unsigned &ns100)
+{
+ const UInt64 v = NWindows::NTime::UnixTime64_To_FileTime64(ts.tv_sec) + ((UInt64)ts.tv_nsec / 100);
+ ns100 = (unsigned)((UInt64)ts.tv_nsec % 100);
+ ft.dwLowDateTime = (DWORD)v;
+ ft.dwHighDateTime = (DWORD)(v >> 32);
+}
+
+void FiTime_To_FILETIME(const CFiTime &ts, FILETIME &ft)
+{
+ const UInt64 v = NWindows::NTime::UnixTime64_To_FileTime64(ts.tv_sec) + ((UInt64)ts.tv_nsec / 100);
+ ft.dwLowDateTime = (DWORD)v;
+ ft.dwHighDateTime = (DWORD)(v >> 32);
+}
+
+#endif
diff --git a/CPP/Windows/TimeUtils.h b/CPP/Windows/TimeUtils.h
index d1d8c150..60ee739f 100644..100755
--- a/CPP/Windows/TimeUtils.h
+++ b/CPP/Windows/TimeUtils.h
@@ -5,28 +5,142 @@
#include "../Common/MyTypes.h"
#include "../Common/MyWindows.h"
+#include "PropVariant.h"
+
+inline UInt64 FILETIME_To_UInt64(const FILETIME &ft)
+{
+ return (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
+}
+
+inline void FILETIME_Clear(FILETIME &ft)
+{
+ ft.dwLowDateTime = 0;
+ ft.dwHighDateTime = 0;
+}
+
+inline bool FILETIME_IsZero(const FILETIME &ft)
+{
+ return (ft.dwHighDateTime == 0 && ft.dwLowDateTime == 0);
+}
+
+
+#ifdef _WIN32
+ #define CFiTime FILETIME
+ #define Compare_FiTime ::CompareFileTime
+ inline void FiTime_To_FILETIME(const CFiTime &ts, FILETIME &ft)
+ {
+ ft = ts;
+ }
+ /*
+ inline void FILETIME_To_FiTime(const FILETIME &ft, CFiTime &ts)
+ {
+ ts = ft;
+ }
+ */
+ inline void FiTime_Clear(CFiTime &ft)
+ {
+ ft.dwLowDateTime = 0;
+ ft.dwHighDateTime = 0;
+ }
+#else
+
+ #include <sys/stat.h>
+
+ #if defined(_AIX)
+ #define CFiTime st_timespec
+ #else
+ #define CFiTime timespec
+ #endif
+ int Compare_FiTime(const CFiTime *a1, const CFiTime *a2);
+ bool FILETIME_To_timespec(const FILETIME &ft, CFiTime &ts);
+ void FiTime_To_FILETIME(const CFiTime &ts, FILETIME &ft);
+ void FiTime_To_FILETIME_ns100(const CFiTime &ts, FILETIME &ft, unsigned &ns100);
+ inline void FiTime_Clear(CFiTime &ft)
+ {
+ ft.tv_sec = 0;
+ ft.tv_nsec = 0;
+ }
+
+ #ifdef __APPLE__
+ #define ST_MTIME(st) st.st_mtimespec
+ #define ST_ATIME(st) st.st_atimespec
+ #define ST_CTIME(st) st.st_ctimespec
+ #else
+ #define ST_MTIME(st) st.st_mtim
+ #define ST_ATIME(st) st.st_atim
+ #define ST_CTIME(st) st.st_ctim
+ #endif
+
+#endif
+
+// void FiTime_Normalize_With_Prec(CFiTime &ft, unsigned prec);
namespace NWindows {
namespace NTime {
-bool DosTimeToFileTime(UInt32 dosTime, FILETIME &fileTime) throw();
-bool FileTimeToDosTime(const FILETIME &fileTime, UInt32 &dosTime) throw();
+bool DosTime_To_FileTime(UInt32 dosTime, FILETIME &fileTime) throw();
+bool UtcFileTime_To_LocalDosTime(const FILETIME &utc, UInt32 &dosTime) throw();
+bool FileTime_To_DosTime(const FILETIME &fileTime, UInt32 &dosTime) throw();
// UInt32 Unix Time : for dates 1970-2106
-UInt64 UnixTimeToFileTime64(UInt32 unixTime) throw();
-void UnixTimeToFileTime(UInt32 unixTime, FILETIME &fileTime) throw();
+UInt64 UnixTime_To_FileTime64(UInt32 unixTime) throw();
+void UnixTime_To_FileTime(UInt32 unixTime, FILETIME &fileTime) throw();
// Int64 Unix Time : negative values for dates before 1970
-UInt64 UnixTime64ToFileTime64(Int64 unixTime) throw();
-bool UnixTime64ToFileTime(Int64 unixTime, FILETIME &fileTime) throw();
+UInt64 UnixTime64_To_FileTime64(Int64 unixTime) throw(); // no check
+bool UnixTime64_To_FileTime64(Int64 unixTime, UInt64 &fileTime) throw();
+bool UnixTime64_To_FileTime(Int64 unixTime, FILETIME &fileTime) throw();
-bool FileTimeToUnixTime(const FILETIME &fileTime, UInt32 &unixTime) throw();
-Int64 FileTimeToUnixTime64(const FILETIME &ft) throw();
+Int64 FileTime64_To_UnixTime64(UInt64 ft64) throw();
+bool FileTime_To_UnixTime(const FILETIME &fileTime, UInt32 &unixTime) throw();
+Int64 FileTime_To_UnixTime64(const FILETIME &ft) throw();
+Int64 FileTime_To_UnixTime64_and_Quantums(const FILETIME &ft, UInt32 &quantums) throw();
bool GetSecondsSince1601(unsigned year, unsigned month, unsigned day,
unsigned hour, unsigned min, unsigned sec, UInt64 &resSeconds) throw();
+
+void GetCurUtc_FiTime(CFiTime &ft) throw();
+#ifdef _WIN32
+#define GetCurUtcFileTime GetCurUtc_FiTime
+#else
void GetCurUtcFileTime(FILETIME &ft) throw();
+#endif
}}
+inline void PropVariant_SetFrom_UnixTime(NWindows::NCOM::CPropVariant &prop, UInt32 unixTime)
+{
+ FILETIME ft;
+ NWindows::NTime::UnixTime_To_FileTime(unixTime, ft);
+ prop.SetAsTimeFrom_FT_Prec(ft, k_PropVar_TimePrec_Unix);
+}
+
+inline void PropVariant_SetFrom_NtfsTime(NWindows::NCOM::CPropVariant &prop, const FILETIME &ft)
+{
+ prop.SetAsTimeFrom_FT_Prec(ft, k_PropVar_TimePrec_100ns);
+}
+
+inline void PropVariant_SetFrom_FiTime(NWindows::NCOM::CPropVariant &prop, const CFiTime &fts)
+{
+ #ifdef _WIN32
+ PropVariant_SetFrom_NtfsTime(prop, fts);
+ #else
+ unsigned ns100;
+ FILETIME ft;
+ FiTime_To_FILETIME_ns100(fts, ft, ns100);
+ prop.SetAsTimeFrom_FT_Prec_Ns100(ft, k_PropVar_TimePrec_1ns, ns100);
+ #endif
+}
+
+inline bool PropVariant_SetFrom_DosTime(NWindows::NCOM::CPropVariant &prop, UInt32 dosTime)
+{
+ FILETIME localFileTime, utc;
+ if (!NWindows::NTime::DosTime_To_FileTime(dosTime, localFileTime))
+ return false;
+ if (!LocalFileTimeToFileTime(&localFileTime, &utc))
+ return false;
+ prop.SetAsTimeFrom_FT_Prec(utc, k_PropVar_TimePrec_DOS);
+ return true;
+}
+
#endif
diff --git a/CPP/Windows/Window.cpp b/CPP/Windows/Window.cpp
index 32af4aab..32af4aab 100644..100755
--- a/CPP/Windows/Window.cpp
+++ b/CPP/Windows/Window.cpp
diff --git a/CPP/Windows/Window.h b/CPP/Windows/Window.h
index 83726c7a..83726c7a 100644..100755
--- a/CPP/Windows/Window.h
+++ b/CPP/Windows/Window.h
diff --git a/DOC/7zC.txt b/DOC/7zC.txt
index 939b720f..939b720f 100644..100755
--- a/DOC/7zC.txt
+++ b/DOC/7zC.txt
diff --git a/DOC/7zFormat.txt b/DOC/7zFormat.txt
index 74cdfa41..74cdfa41 100644..100755
--- a/DOC/7zFormat.txt
+++ b/DOC/7zFormat.txt
diff --git a/DOC/7zip.hhp b/DOC/7zip.hhp
index 6c6bd708..6c6bd708 100644..100755
--- a/DOC/7zip.hhp
+++ b/DOC/7zip.hhp
diff --git a/DOC/7zip.wxs b/DOC/7zip.wxs
index fdc63cea..c7a61b44 100644..100755
--- a/DOC/7zip.wxs
+++ b/DOC/7zip.wxs
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
-<?define VerMajor = "21" ?>
-<?define VerMinor = "07" ?>
+<?define VerMajor = "22" ?>
+<?define VerMinor = "00" ?>
<?define VerBuild = "00" ?>
<?define MmVer = "$(var.VerMajor).$(var.VerMinor)" ?>
<?define MmHex = "$(var.VerMajor)$(var.VerMinor)" ?>
diff --git a/DOC/License.txt b/DOC/License.txt
index c9e858fe..c9e858fe 100644..100755
--- a/DOC/License.txt
+++ b/DOC/License.txt
diff --git a/DOC/Methods.txt b/DOC/Methods.txt
index d4a1b1dd..d4a1b1dd 100644..100755
--- a/DOC/Methods.txt
+++ b/DOC/Methods.txt
diff --git a/DOC/copying.txt b/DOC/copying.txt
index 4362b491..4362b491 100644..100755
--- a/DOC/copying.txt
+++ b/DOC/copying.txt
diff --git a/DOC/lzma.txt b/DOC/lzma.txt
index a65988fe..a65988fe 100644..100755
--- a/DOC/lzma.txt
+++ b/DOC/lzma.txt
diff --git a/DOC/readme.txt b/DOC/readme.txt
index 0f6c77ba..0f6c77ba 100644..100755
--- a/DOC/readme.txt
+++ b/DOC/readme.txt
diff --git a/DOC/src-history.txt b/DOC/src-history.txt
index 0b54fe34..f546c4e2 100644..100755
--- a/DOC/src-history.txt
+++ b/DOC/src-history.txt
@@ -1,6 +1,12 @@
HISTORY of the 7-Zip source code
--------------------------------
+22.00 2022-06-16
+-------------------------
+- 7-Zip interfaces now support high precision (1 ns) timestamps with reserved
+ fields of tagPROPVARIANT (VT_FILETIME).
+
+
21.07 2021-12-26
-------------------------
- The sorting order of files in archives was slightly changed to be more consistent
diff --git a/DOC/unRarLicense.txt b/DOC/unRarLicense.txt
index 5f78b728..5f78b728 100644..100755
--- a/DOC/unRarLicense.txt
+++ b/DOC/unRarLicense.txt