From ec44a8a0700a8b2444b07f576be332f756754323 Mon Sep 17 00:00:00 2001 From: Igor Pavlov Date: Thu, 23 Jun 2022 11:43:16 +0100 Subject: [PATCH] 22.00 --- Asm/arm/7zCrcOpt.asm | 0 Asm/arm64/7zAsm.S | 0 Asm/arm64/LzmaDecOpt.S | 0 Asm/x86/7zAsm.asm | 7 +- Asm/x86/7zCrcOpt.asm | 0 Asm/x86/AesOpt.asm | 0 Asm/x86/LzFindOpt.asm | 0 Asm/x86/LzmaDecOpt.asm | 0 Asm/x86/Sha1Opt.asm | 0 Asm/x86/Sha256Opt.asm | 32 +- Asm/x86/XzCrc64Opt.asm | 0 C/7z.h | 0 C/7zAlloc.c | 0 C/7zAlloc.h | 0 C/7zArcIn.c | 0 C/7zBuf.c | 0 C/7zBuf.h | 0 C/7zBuf2.c | 0 C/7zCrc.c | 0 C/7zCrc.h | 0 C/7zCrcOpt.c | 0 C/7zDec.c | 0 C/7zFile.c | 0 C/7zFile.h | 0 C/7zStream.c | 0 C/7zTypes.h | 14 +- C/7zVersion.h | 10 +- C/7zVersion.rc | 0 C/7zip_gcc_c.mak | 0 C/Aes.c | 0 C/Aes.h | 0 C/AesOpt.c | 0 C/Alloc.c | 0 C/Alloc.h | 0 C/Bcj2.c | 0 C/Bcj2.h | 0 C/Bcj2Enc.c | 0 C/Blake2.h | 0 C/Blake2s.c | 0 C/Bra.c | 0 C/Bra.h | 0 C/Bra86.c | 0 C/BraIA64.c | 0 C/BwtSort.c | 0 C/BwtSort.h | 0 C/Compiler.h | 0 C/CpuArch.c | 0 C/CpuArch.h | 0 C/Delta.c | 0 C/Delta.h | 0 C/DllSecur.c | 0 C/DllSecur.h | 0 C/HuffEnc.c | 0 C/HuffEnc.h | 0 C/LzFind.c | 0 C/LzFind.h | 0 C/LzFindMt.c | 0 C/LzFindMt.h | 0 C/LzFindOpt.c | 0 C/LzHash.h | 0 C/Lzma2Dec.c | 0 C/Lzma2Dec.h | 0 C/Lzma2DecMt.c | 0 C/Lzma2DecMt.h | 0 C/Lzma2Enc.c | 0 C/Lzma2Enc.h | 0 C/Lzma86.h | 0 C/Lzma86Dec.c | 0 C/Lzma86Enc.c | 0 C/LzmaDec.c | 0 C/LzmaDec.h | 0 C/LzmaEnc.c | 0 C/LzmaEnc.h | 0 C/LzmaLib.c | 0 C/LzmaLib.h | 0 C/MtCoder.c | 0 C/MtCoder.h | 0 C/MtDec.c | 0 C/MtDec.h | 0 C/Ppmd.h | 0 C/Ppmd7.c | 0 C/Ppmd7.h | 0 C/Ppmd7Dec.c | 0 C/Ppmd7Enc.c | 0 C/Ppmd7aDec.c | 0 C/Ppmd8.c | 0 C/Ppmd8.h | 0 C/Ppmd8Dec.c | 0 C/Ppmd8Enc.c | 0 C/Precomp.h | 0 C/RotateDefs.h | 0 C/Sha1.c | 0 C/Sha1.h | 0 C/Sha1Opt.c | 0 C/Sha256.c | 0 C/Sha256.h | 0 C/Sha256Opt.c | 0 C/Sort.c | 0 C/Sort.h | 0 C/Threads.c | 0 C/Threads.h | 0 C/Util/7z/7z.dsp | 0 C/Util/7z/7z.dsw | 0 C/Util/7z/7zMain.c | 0 C/Util/7z/Precomp.c | 0 C/Util/7z/Precomp.h | 0 C/Util/7z/makefile | 0 C/Util/7z/makefile.gcc | 0 C/Util/7zipInstall/7zip.ico | Bin C/Util/7zipInstall/7zipInstall.c | 0 C/Util/7zipInstall/7zipInstall.dsp | 0 C/Util/7zipInstall/7zipInstall.dsw | 0 C/Util/7zipInstall/7zipInstall.manifest | 0 C/Util/7zipInstall/Precomp.c | 0 C/Util/7zipInstall/Precomp.h | 0 C/Util/7zipInstall/makefile | 0 C/Util/7zipInstall/resource.h | 0 C/Util/7zipInstall/resource.rc | 0 C/Util/7zipUninstall/7zipUninstall.c | 0 C/Util/7zipUninstall/7zipUninstall.dsp | 0 C/Util/7zipUninstall/7zipUninstall.dsw | 0 C/Util/7zipUninstall/7zipUninstall.ico | Bin C/Util/7zipUninstall/7zipUninstall.manifest | 0 C/Util/7zipUninstall/Precomp.c | 0 C/Util/7zipUninstall/Precomp.h | 0 C/Util/7zipUninstall/makefile | 0 C/Util/7zipUninstall/resource.h | 0 C/Util/7zipUninstall/resource.rc | 0 C/Util/Lzma/LzmaUtil.c | 0 C/Util/Lzma/LzmaUtil.dsp | 0 C/Util/Lzma/LzmaUtil.dsw | 0 C/Util/Lzma/makefile | 0 C/Util/Lzma/makefile.gcc | 0 C/Util/LzmaLib/LzmaLib.def | 0 C/Util/LzmaLib/LzmaLib.dsp | 0 C/Util/LzmaLib/LzmaLib.dsw | 0 C/Util/LzmaLib/LzmaLibExports.c | 0 C/Util/LzmaLib/makefile | 0 C/Util/LzmaLib/resource.rc | 0 C/Util/SfxSetup/Precomp.c | 0 C/Util/SfxSetup/Precomp.h | 0 C/Util/SfxSetup/SfxSetup.c | 0 C/Util/SfxSetup/SfxSetup.dsp | 0 C/Util/SfxSetup/SfxSetup.dsw | 0 C/Util/SfxSetup/makefile | 0 C/Util/SfxSetup/makefile_con | 0 C/Util/SfxSetup/resource.rc | 0 C/Util/SfxSetup/setup.ico | Bin C/Xz.c | 0 C/Xz.h | 0 C/XzCrc64.c | 0 C/XzCrc64.h | 0 C/XzCrc64Opt.c | 0 C/XzDec.c | 0 C/XzEnc.c | 0 C/XzEnc.h | 0 C/XzIn.c | 0 C/var_clang.mak | 0 C/var_clang_arm64.mak | 0 C/var_clang_x64.mak | 0 C/var_clang_x86.mak | 0 C/var_gcc.mak | 0 C/var_gcc_arm64.mak | 0 C/var_gcc_x64.mak | 0 C/var_gcc_x86.mak | 0 C/var_mac_arm64.mak | 0 C/var_mac_x64.mak | 0 C/warn_clang.mak | 0 C/warn_clang_mac.mak | 0 C/warn_gcc.mak | 0 CPP/7zip/7zip.mak | 0 CPP/7zip/7zip_gcc.mak | 8 + CPP/7zip/Aes.mak | 0 CPP/7zip/Archive/7z/7z.dsp | 0 CPP/7zip/Archive/7z/7z.dsw | 0 CPP/7zip/Archive/7z/7zCompressionMode.cpp | 0 CPP/7zip/Archive/7z/7zCompressionMode.h | 0 CPP/7zip/Archive/7z/7zDecode.cpp | 0 CPP/7zip/Archive/7z/7zDecode.h | 0 CPP/7zip/Archive/7z/7zEncode.cpp | 0 CPP/7zip/Archive/7z/7zEncode.h | 0 CPP/7zip/Archive/7z/7zExtract.cpp | 0 CPP/7zip/Archive/7z/7zFolderInStream.cpp | 123 +- CPP/7zip/Archive/7z/7zFolderInStream.h | 31 +- CPP/7zip/Archive/7z/7zHandler.cpp | 2 +- CPP/7zip/Archive/7z/7zHandler.h | 5 +- CPP/7zip/Archive/7z/7zHandlerOut.cpp | 39 +- CPP/7zip/Archive/7z/7zHeader.cpp | 0 CPP/7zip/Archive/7z/7zHeader.h | 0 CPP/7zip/Archive/7z/7zIn.cpp | 0 CPP/7zip/Archive/7z/7zIn.h | 0 CPP/7zip/Archive/7z/7zItem.h | 0 CPP/7zip/Archive/7z/7zOut.cpp | 0 CPP/7zip/Archive/7z/7zOut.h | 0 CPP/7zip/Archive/7z/7zProperties.cpp | 0 CPP/7zip/Archive/7z/7zProperties.h | 0 CPP/7zip/Archive/7z/7zRegister.cpp | 10 +- CPP/7zip/Archive/7z/7zSpecStream.cpp | 0 CPP/7zip/Archive/7z/7zSpecStream.h | 0 CPP/7zip/Archive/7z/7zUpdate.cpp | 141 +- CPP/7zip/Archive/7z/7zUpdate.h | 14 +- CPP/7zip/Archive/7z/StdAfx.cpp | 0 CPP/7zip/Archive/7z/StdAfx.h | 0 CPP/7zip/Archive/7z/makefile | 0 CPP/7zip/Archive/7z/resource.rc | 0 CPP/7zip/Archive/ApfsHandler.cpp | 3546 +++++++++++++++++ CPP/7zip/Archive/ApmHandler.cpp | 0 CPP/7zip/Archive/ArHandler.cpp | 14 +- CPP/7zip/Archive/Archive.def | 0 CPP/7zip/Archive/Archive2.def | 0 CPP/7zip/Archive/ArchiveExports.cpp | 1 + CPP/7zip/Archive/ArjHandler.cpp | 10 +- CPP/7zip/Archive/Base64Handler.cpp | 0 CPP/7zip/Archive/Bz2Handler.cpp | 100 +- CPP/7zip/Archive/Cab/CabBlockInStream.cpp | 0 CPP/7zip/Archive/Cab/CabBlockInStream.h | 0 CPP/7zip/Archive/Cab/CabHandler.cpp | 10 +- CPP/7zip/Archive/Cab/CabHandler.h | 0 CPP/7zip/Archive/Cab/CabHeader.cpp | 0 CPP/7zip/Archive/Cab/CabHeader.h | 0 CPP/7zip/Archive/Cab/CabIn.cpp | 0 CPP/7zip/Archive/Cab/CabIn.h | 0 CPP/7zip/Archive/Cab/CabItem.h | 0 CPP/7zip/Archive/Cab/CabRegister.cpp | 0 CPP/7zip/Archive/Cab/StdAfx.h | 0 CPP/7zip/Archive/Chm/ChmHandler.cpp | 0 CPP/7zip/Archive/Chm/ChmHandler.h | 0 CPP/7zip/Archive/Chm/ChmIn.cpp | 0 CPP/7zip/Archive/Chm/ChmIn.h | 11 + CPP/7zip/Archive/Chm/StdAfx.h | 0 CPP/7zip/Archive/ComHandler.cpp | 0 CPP/7zip/Archive/Common/CoderMixer2.cpp | 0 CPP/7zip/Archive/Common/CoderMixer2.h | 0 CPP/7zip/Archive/Common/DummyOutStream.cpp | 0 CPP/7zip/Archive/Common/DummyOutStream.h | 0 CPP/7zip/Archive/Common/FindSignature.cpp | 0 CPP/7zip/Archive/Common/FindSignature.h | 0 CPP/7zip/Archive/Common/HandlerOut.cpp | 77 +- CPP/7zip/Archive/Common/HandlerOut.h | 26 + CPP/7zip/Archive/Common/InStreamWithCRC.cpp | 0 CPP/7zip/Archive/Common/InStreamWithCRC.h | 0 CPP/7zip/Archive/Common/ItemNameUtils.cpp | 23 + CPP/7zip/Archive/Common/ItemNameUtils.h | 2 + CPP/7zip/Archive/Common/MultiStream.cpp | 0 CPP/7zip/Archive/Common/MultiStream.h | 0 CPP/7zip/Archive/Common/OutStreamWithCRC.cpp | 0 CPP/7zip/Archive/Common/OutStreamWithCRC.h | 0 CPP/7zip/Archive/Common/OutStreamWithSha1.cpp | 0 CPP/7zip/Archive/Common/OutStreamWithSha1.h | 0 CPP/7zip/Archive/Common/ParseProperties.cpp | 0 CPP/7zip/Archive/Common/ParseProperties.h | 0 CPP/7zip/Archive/Common/StdAfx.h | 0 CPP/7zip/Archive/CpioHandler.cpp | 6 +- CPP/7zip/Archive/CramfsHandler.cpp | 0 CPP/7zip/Archive/DeflateProps.cpp | 0 CPP/7zip/Archive/DeflateProps.h | 0 CPP/7zip/Archive/DllExports.cpp | 0 CPP/7zip/Archive/DllExports2.cpp | 18 + CPP/7zip/Archive/DmgHandler.cpp | 0 CPP/7zip/Archive/ElfHandler.cpp | 0 CPP/7zip/Archive/ExtHandler.cpp | 51 +- CPP/7zip/Archive/FatHandler.cpp | 15 +- CPP/7zip/Archive/FlvHandler.cpp | 0 CPP/7zip/Archive/GptHandler.cpp | 75 +- CPP/7zip/Archive/GzHandler.cpp | 217 +- CPP/7zip/Archive/HandlerCont.cpp | 55 +- CPP/7zip/Archive/HandlerCont.h | 12 + CPP/7zip/Archive/HfsHandler.cpp | 21 +- CPP/7zip/Archive/IArchive.h | 89 +- CPP/7zip/Archive/Icons/7z.ico | Bin CPP/7zip/Archive/Icons/apfs.ico | Bin 0 -> 3638 bytes CPP/7zip/Archive/Icons/arj.ico | Bin CPP/7zip/Archive/Icons/bz2.ico | Bin CPP/7zip/Archive/Icons/cab.ico | Bin CPP/7zip/Archive/Icons/cpio.ico | Bin CPP/7zip/Archive/Icons/deb.ico | Bin CPP/7zip/Archive/Icons/dmg.ico | Bin CPP/7zip/Archive/Icons/fat.ico | Bin CPP/7zip/Archive/Icons/gz.ico | Bin CPP/7zip/Archive/Icons/hfs.ico | Bin CPP/7zip/Archive/Icons/iso.ico | Bin CPP/7zip/Archive/Icons/lzh.ico | Bin CPP/7zip/Archive/Icons/lzma.ico | Bin CPP/7zip/Archive/Icons/ntfs.ico | Bin CPP/7zip/Archive/Icons/rar.ico | Bin CPP/7zip/Archive/Icons/rpm.ico | Bin CPP/7zip/Archive/Icons/split.ico | Bin CPP/7zip/Archive/Icons/squashfs.ico | Bin CPP/7zip/Archive/Icons/tar.ico | Bin CPP/7zip/Archive/Icons/vhd.ico | Bin CPP/7zip/Archive/Icons/wim.ico | Bin CPP/7zip/Archive/Icons/xar.ico | Bin CPP/7zip/Archive/Icons/xz.ico | Bin CPP/7zip/Archive/Icons/z.ico | Bin CPP/7zip/Archive/Icons/zip.ico | Bin CPP/7zip/Archive/IhexHandler.cpp | 0 CPP/7zip/Archive/Iso/IsoHandler.cpp | 24 +- CPP/7zip/Archive/Iso/IsoHandler.h | 0 CPP/7zip/Archive/Iso/IsoHeader.cpp | 0 CPP/7zip/Archive/Iso/IsoHeader.h | 0 CPP/7zip/Archive/Iso/IsoIn.cpp | 2 + CPP/7zip/Archive/Iso/IsoIn.h | 15 +- CPP/7zip/Archive/Iso/IsoItem.h | 13 +- CPP/7zip/Archive/Iso/IsoRegister.cpp | 0 CPP/7zip/Archive/Iso/StdAfx.h | 0 CPP/7zip/Archive/LpHandler.cpp | 1173 ++++++ CPP/7zip/Archive/LzhHandler.cpp | 15 +- CPP/7zip/Archive/LzmaHandler.cpp | 0 CPP/7zip/Archive/MachoHandler.cpp | 0 CPP/7zip/Archive/MbrHandler.cpp | 0 CPP/7zip/Archive/MslzHandler.cpp | 0 CPP/7zip/Archive/MubHandler.cpp | 0 CPP/7zip/Archive/Nsis/NsisDecode.cpp | 0 CPP/7zip/Archive/Nsis/NsisDecode.h | 0 CPP/7zip/Archive/Nsis/NsisHandler.cpp | 0 CPP/7zip/Archive/Nsis/NsisHandler.h | 0 CPP/7zip/Archive/Nsis/NsisIn.cpp | 0 CPP/7zip/Archive/Nsis/NsisIn.h | 0 CPP/7zip/Archive/Nsis/NsisRegister.cpp | 0 CPP/7zip/Archive/Nsis/StdAfx.h | 0 CPP/7zip/Archive/NtfsHandler.cpp | 7 +- CPP/7zip/Archive/PeHandler.cpp | 6 +- CPP/7zip/Archive/PpmdHandler.cpp | 2 +- CPP/7zip/Archive/QcowHandler.cpp | 0 CPP/7zip/Archive/Rar/Rar5Handler.cpp | 44 +- CPP/7zip/Archive/Rar/Rar5Handler.h | 0 CPP/7zip/Archive/Rar/RarHandler.cpp | 41 +- CPP/7zip/Archive/Rar/RarHandler.h | 0 CPP/7zip/Archive/Rar/RarHeader.h | 0 CPP/7zip/Archive/Rar/RarItem.h | 0 CPP/7zip/Archive/Rar/RarVol.h | 17 +- CPP/7zip/Archive/Rar/StdAfx.cpp | 0 CPP/7zip/Archive/Rar/StdAfx.h | 0 CPP/7zip/Archive/RpmHandler.cpp | 6 +- CPP/7zip/Archive/SparseHandler.cpp | 548 +++ CPP/7zip/Archive/SplitHandler.cpp | 7 +- CPP/7zip/Archive/SquashfsHandler.cpp | 155 +- CPP/7zip/Archive/StdAfx.h | 0 CPP/7zip/Archive/SwfHandler.cpp | 0 CPP/7zip/Archive/Tar/StdAfx.h | 0 CPP/7zip/Archive/Tar/TarHandler.cpp | 445 ++- CPP/7zip/Archive/Tar/TarHandler.h | 27 +- CPP/7zip/Archive/Tar/TarHandlerOut.cpp | 209 +- CPP/7zip/Archive/Tar/TarHeader.cpp | 77 +- CPP/7zip/Archive/Tar/TarHeader.h | 8 +- CPP/7zip/Archive/Tar/TarIn.cpp | 945 ++++- CPP/7zip/Archive/Tar/TarIn.h | 130 +- CPP/7zip/Archive/Tar/TarItem.h | 246 +- CPP/7zip/Archive/Tar/TarOut.cpp | 561 ++- CPP/7zip/Archive/Tar/TarOut.h | 31 +- CPP/7zip/Archive/Tar/TarRegister.cpp | 16 +- CPP/7zip/Archive/Tar/TarUpdate.cpp | 406 +- CPP/7zip/Archive/Tar/TarUpdate.h | 39 +- CPP/7zip/Archive/Udf/StdAfx.h | 0 CPP/7zip/Archive/Udf/UdfHandler.cpp | 20 +- CPP/7zip/Archive/Udf/UdfHandler.h | 0 CPP/7zip/Archive/Udf/UdfIn.cpp | 2 +- CPP/7zip/Archive/Udf/UdfIn.h | 2 +- CPP/7zip/Archive/UefiHandler.cpp | 0 CPP/7zip/Archive/VdiHandler.cpp | 0 CPP/7zip/Archive/VhdHandler.cpp | 3 +- CPP/7zip/Archive/VhdxHandler.cpp | 28 +- CPP/7zip/Archive/VmdkHandler.cpp | 2 +- CPP/7zip/Archive/Wim/StdAfx.h | 0 CPP/7zip/Archive/Wim/WimHandler.cpp | 3 +- CPP/7zip/Archive/Wim/WimHandler.h | 0 CPP/7zip/Archive/Wim/WimHandlerOut.cpp | 14 +- CPP/7zip/Archive/Wim/WimIn.cpp | 9 +- CPP/7zip/Archive/Wim/WimIn.h | 0 CPP/7zip/Archive/Wim/WimRegister.cpp | 21 +- CPP/7zip/Archive/XarHandler.cpp | 0 CPP/7zip/Archive/XzHandler.cpp | 43 +- CPP/7zip/Archive/XzHandler.h | 0 CPP/7zip/Archive/ZHandler.cpp | 0 CPP/7zip/Archive/Zip/StdAfx.h | 0 CPP/7zip/Archive/Zip/ZipAddCommon.cpp | 0 CPP/7zip/Archive/Zip/ZipAddCommon.h | 0 CPP/7zip/Archive/Zip/ZipCompressionMode.h | 0 CPP/7zip/Archive/Zip/ZipHandler.cpp | 178 +- CPP/7zip/Archive/Zip/ZipHandler.h | 7 +- CPP/7zip/Archive/Zip/ZipHandlerOut.cpp | 81 +- CPP/7zip/Archive/Zip/ZipHeader.h | 9 +- CPP/7zip/Archive/Zip/ZipIn.cpp | 23 +- CPP/7zip/Archive/Zip/ZipIn.h | 0 CPP/7zip/Archive/Zip/ZipItem.cpp | 68 +- CPP/7zip/Archive/Zip/ZipItem.h | 5 +- CPP/7zip/Archive/Zip/ZipOut.cpp | 86 +- CPP/7zip/Archive/Zip/ZipOut.h | 9 +- CPP/7zip/Archive/Zip/ZipRegister.cpp | 18 +- CPP/7zip/Archive/Zip/ZipUpdate.cpp | 171 +- CPP/7zip/Archive/Zip/ZipUpdate.h | 28 +- CPP/7zip/Archive/makefile | 0 CPP/7zip/Asm.mak | 0 CPP/7zip/Bundles/Alone/Alone.dsp | 0 CPP/7zip/Bundles/Alone/Alone.dsw | 0 CPP/7zip/Bundles/Alone/StdAfx.cpp | 0 CPP/7zip/Bundles/Alone/StdAfx.h | 0 CPP/7zip/Bundles/Alone/afxres.h | 0 CPP/7zip/Bundles/Alone/makefile | 0 CPP/7zip/Bundles/Alone/makefile.gcc | 0 CPP/7zip/Bundles/Alone/resource.rc | 0 CPP/7zip/Bundles/Alone2/StdAfx.cpp | 0 CPP/7zip/Bundles/Alone2/StdAfx.h | 0 CPP/7zip/Bundles/Alone2/makefile | 1 - CPP/7zip/Bundles/Alone2/makefile.gcc | 1 - CPP/7zip/Bundles/Alone2/resource.rc | 0 CPP/7zip/Bundles/Alone7z/Alone.dsp | 0 CPP/7zip/Bundles/Alone7z/Alone.dsw | 0 CPP/7zip/Bundles/Alone7z/StdAfx.cpp | 0 CPP/7zip/Bundles/Alone7z/StdAfx.h | 0 CPP/7zip/Bundles/Alone7z/makefile | 0 CPP/7zip/Bundles/Alone7z/makefile.gcc | 0 CPP/7zip/Bundles/Alone7z/resource.rc | 0 CPP/7zip/Bundles/Fm/FM.dsp | 0 CPP/7zip/Bundles/Fm/FM.dsw | 0 CPP/7zip/Bundles/Fm/StdAfx.cpp | 0 CPP/7zip/Bundles/Fm/StdAfx.h | 0 CPP/7zip/Bundles/Fm/makefile | 1 - CPP/7zip/Bundles/Fm/resource.rc | 2 +- CPP/7zip/Bundles/Format7z/StdAfx.cpp | 0 CPP/7zip/Bundles/Format7z/StdAfx.h | 0 CPP/7zip/Bundles/Format7z/makefile | 0 CPP/7zip/Bundles/Format7z/resource.rc | 0 CPP/7zip/Bundles/Format7zExtract/StdAfx.cpp | 0 CPP/7zip/Bundles/Format7zExtract/StdAfx.h | 0 CPP/7zip/Bundles/Format7zExtract/makefile | 0 CPP/7zip/Bundles/Format7zExtract/resource.rc | 0 CPP/7zip/Bundles/Format7zExtractR/StdAfx.cpp | 0 CPP/7zip/Bundles/Format7zExtractR/StdAfx.h | 0 CPP/7zip/Bundles/Format7zExtractR/makefile | 0 CPP/7zip/Bundles/Format7zExtractR/resource.rc | 0 CPP/7zip/Bundles/Format7zF/Arc.mak | 4 + CPP/7zip/Bundles/Format7zF/Arc_gcc.mak | 4 + CPP/7zip/Bundles/Format7zF/Format7z.dsp | 20 + CPP/7zip/Bundles/Format7zF/Format7z.dsw | 0 CPP/7zip/Bundles/Format7zF/StdAfx.cpp | 0 CPP/7zip/Bundles/Format7zF/StdAfx.h | 0 CPP/7zip/Bundles/Format7zF/makefile | 0 CPP/7zip/Bundles/Format7zF/makefile.gcc | 0 CPP/7zip/Bundles/Format7zF/resource.rc | 3 +- CPP/7zip/Bundles/Format7zR/StdAfx.cpp | 0 CPP/7zip/Bundles/Format7zR/StdAfx.h | 0 CPP/7zip/Bundles/Format7zR/makefile | 0 CPP/7zip/Bundles/Format7zR/resource.rc | 0 CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp | 2 +- CPP/7zip/Bundles/LzmaCon/LzmaCon.dsp | 0 CPP/7zip/Bundles/LzmaCon/LzmaCon.dsw | 0 CPP/7zip/Bundles/LzmaCon/StdAfx.cpp | 0 CPP/7zip/Bundles/LzmaCon/StdAfx.h | 0 CPP/7zip/Bundles/LzmaCon/makefile | 0 CPP/7zip/Bundles/LzmaCon/makefile.gcc | 0 CPP/7zip/Bundles/LzmaCon/resource.rc | 0 CPP/7zip/Bundles/SFXCon/7z.ico | Bin CPP/7zip/Bundles/SFXCon/SFXCon.dsp | 0 CPP/7zip/Bundles/SFXCon/SFXCon.dsw | 0 CPP/7zip/Bundles/SFXCon/SfxCon.cpp | 0 CPP/7zip/Bundles/SFXCon/StdAfx.cpp | 0 CPP/7zip/Bundles/SFXCon/StdAfx.h | 0 CPP/7zip/Bundles/SFXCon/makefile | 0 CPP/7zip/Bundles/SFXCon/makefile.gcc | 0 CPP/7zip/Bundles/SFXCon/resource.rc | 0 .../Bundles/SFXSetup/ExtractCallbackSfx.cpp | 0 .../Bundles/SFXSetup/ExtractCallbackSfx.h | 0 CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp | 0 CPP/7zip/Bundles/SFXSetup/ExtractEngine.h | 0 CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp | 0 CPP/7zip/Bundles/SFXSetup/SFXSetup.dsw | 0 CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp | 0 CPP/7zip/Bundles/SFXSetup/StdAfx.cpp | 0 CPP/7zip/Bundles/SFXSetup/StdAfx.h | 0 CPP/7zip/Bundles/SFXSetup/makefile | 0 CPP/7zip/Bundles/SFXSetup/resource.h | 0 CPP/7zip/Bundles/SFXSetup/resource.rc | 0 CPP/7zip/Bundles/SFXSetup/setup.ico | Bin CPP/7zip/Bundles/SFXWin/7z.ico | Bin CPP/7zip/Bundles/SFXWin/SFXWin.dsp | 0 CPP/7zip/Bundles/SFXWin/SFXWin.dsw | 0 CPP/7zip/Bundles/SFXWin/SfxWin.cpp | 0 CPP/7zip/Bundles/SFXWin/StdAfx.cpp | 0 CPP/7zip/Bundles/SFXWin/StdAfx.h | 0 CPP/7zip/Bundles/SFXWin/makefile | 0 CPP/7zip/Bundles/SFXWin/resource.h | 0 CPP/7zip/Bundles/SFXWin/resource.rc | 0 CPP/7zip/Bundles/makefile | 0 CPP/7zip/Common/CWrappers.cpp | 0 CPP/7zip/Common/CWrappers.h | 0 CPP/7zip/Common/CreateCoder.cpp | 0 CPP/7zip/Common/CreateCoder.h | 0 CPP/7zip/Common/FilePathAutoRename.cpp | 0 CPP/7zip/Common/FilePathAutoRename.h | 0 CPP/7zip/Common/FileStreams.cpp | 292 +- CPP/7zip/Common/FileStreams.h | 42 +- CPP/7zip/Common/FilterCoder.cpp | 0 CPP/7zip/Common/FilterCoder.h | 0 CPP/7zip/Common/InBuffer.cpp | 3 +- CPP/7zip/Common/InBuffer.h | 0 CPP/7zip/Common/InOutTempBuffer.cpp | 0 CPP/7zip/Common/InOutTempBuffer.h | 0 CPP/7zip/Common/LimitedStreams.cpp | 68 +- CPP/7zip/Common/LimitedStreams.h | 21 +- CPP/7zip/Common/LockedStream.cpp | 0 CPP/7zip/Common/LockedStream.h | 0 CPP/7zip/Common/MemBlocks.cpp | 0 CPP/7zip/Common/MemBlocks.h | 0 CPP/7zip/Common/MethodId.cpp | 0 CPP/7zip/Common/MethodId.h | 0 CPP/7zip/Common/MethodProps.cpp | 0 CPP/7zip/Common/MethodProps.h | 0 CPP/7zip/Common/OffsetStream.cpp | 0 CPP/7zip/Common/OffsetStream.h | 0 CPP/7zip/Common/OutBuffer.cpp | 0 CPP/7zip/Common/OutBuffer.h | 0 CPP/7zip/Common/OutMemStream.cpp | 0 CPP/7zip/Common/OutMemStream.h | 0 CPP/7zip/Common/ProgressMt.cpp | 0 CPP/7zip/Common/ProgressMt.h | 0 CPP/7zip/Common/ProgressUtils.cpp | 0 CPP/7zip/Common/ProgressUtils.h | 0 CPP/7zip/Common/PropId.cpp | 9 +- CPP/7zip/Common/RegisterArc.h | 24 +- CPP/7zip/Common/RegisterCodec.h | 0 CPP/7zip/Common/StdAfx.h | 0 CPP/7zip/Common/StreamBinder.cpp | 0 CPP/7zip/Common/StreamBinder.h | 0 CPP/7zip/Common/StreamObjects.cpp | 0 CPP/7zip/Common/StreamObjects.h | 0 CPP/7zip/Common/StreamUtils.cpp | 0 CPP/7zip/Common/StreamUtils.h | 0 CPP/7zip/Common/UniqBlocks.cpp | 8 +- CPP/7zip/Common/UniqBlocks.h | 19 +- CPP/7zip/Common/VirtThread.cpp | 0 CPP/7zip/Common/VirtThread.h | 0 CPP/7zip/Compress/BZip2Const.h | 0 CPP/7zip/Compress/BZip2Crc.cpp | 0 CPP/7zip/Compress/BZip2Crc.h | 0 CPP/7zip/Compress/BZip2Decoder.cpp | 0 CPP/7zip/Compress/BZip2Decoder.h | 0 CPP/7zip/Compress/BZip2Encoder.cpp | 23 +- CPP/7zip/Compress/BZip2Encoder.h | 6 +- CPP/7zip/Compress/BZip2Register.cpp | 0 CPP/7zip/Compress/Bcj2Coder.cpp | 0 CPP/7zip/Compress/Bcj2Coder.h | 0 CPP/7zip/Compress/Bcj2Register.cpp | 0 CPP/7zip/Compress/BcjCoder.cpp | 0 CPP/7zip/Compress/BcjCoder.h | 0 CPP/7zip/Compress/BcjRegister.cpp | 0 CPP/7zip/Compress/BitlDecoder.cpp | 0 CPP/7zip/Compress/BitlDecoder.h | 4 + CPP/7zip/Compress/BitlEncoder.h | 0 CPP/7zip/Compress/BitmDecoder.h | 0 CPP/7zip/Compress/BitmEncoder.h | 0 CPP/7zip/Compress/BranchMisc.cpp | 0 CPP/7zip/Compress/BranchMisc.h | 0 CPP/7zip/Compress/BranchRegister.cpp | 0 CPP/7zip/Compress/ByteSwap.cpp | 0 CPP/7zip/Compress/Codec.def | 0 CPP/7zip/Compress/CodecExports.cpp | 0 CPP/7zip/Compress/CopyCoder.cpp | 0 CPP/7zip/Compress/CopyCoder.h | 0 CPP/7zip/Compress/CopyRegister.cpp | 0 CPP/7zip/Compress/Deflate64Register.cpp | 0 CPP/7zip/Compress/DeflateConst.h | 0 CPP/7zip/Compress/DeflateDecoder.cpp | 1 - CPP/7zip/Compress/DeflateDecoder.h | 0 CPP/7zip/Compress/DeflateEncoder.cpp | 0 CPP/7zip/Compress/DeflateEncoder.h | 0 CPP/7zip/Compress/DeflateRegister.cpp | 0 CPP/7zip/Compress/DeltaFilter.cpp | 0 CPP/7zip/Compress/DllExports2Compress.cpp | 0 CPP/7zip/Compress/DllExportsCompress.cpp | 0 CPP/7zip/Compress/HuffmanDecoder.h | 0 CPP/7zip/Compress/ImplodeDecoder.cpp | 0 CPP/7zip/Compress/ImplodeDecoder.h | 0 CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp | 0 CPP/7zip/Compress/ImplodeHuffmanDecoder.h | 0 CPP/7zip/Compress/LzOutWindow.cpp | 0 CPP/7zip/Compress/LzOutWindow.h | 0 CPP/7zip/Compress/LzfseDecoder.cpp | 0 CPP/7zip/Compress/LzfseDecoder.h | 0 CPP/7zip/Compress/LzhDecoder.cpp | 0 CPP/7zip/Compress/LzhDecoder.h | 0 CPP/7zip/Compress/Lzma2Decoder.cpp | 0 CPP/7zip/Compress/Lzma2Decoder.h | 0 CPP/7zip/Compress/Lzma2Encoder.cpp | 0 CPP/7zip/Compress/Lzma2Encoder.h | 0 CPP/7zip/Compress/Lzma2Register.cpp | 0 CPP/7zip/Compress/LzmaDecoder.cpp | 0 CPP/7zip/Compress/LzmaDecoder.h | 0 CPP/7zip/Compress/LzmaEncoder.cpp | 7 +- CPP/7zip/Compress/LzmaEncoder.h | 0 CPP/7zip/Compress/LzmaRegister.cpp | 0 CPP/7zip/Compress/LzmsDecoder.cpp | 0 CPP/7zip/Compress/LzmsDecoder.h | 0 CPP/7zip/Compress/Lzx.h | 0 CPP/7zip/Compress/LzxDecoder.cpp | 0 CPP/7zip/Compress/LzxDecoder.h | 0 CPP/7zip/Compress/Mtf8.h | 0 CPP/7zip/Compress/PpmdDecoder.cpp | 0 CPP/7zip/Compress/PpmdDecoder.h | 0 CPP/7zip/Compress/PpmdEncoder.cpp | 0 CPP/7zip/Compress/PpmdEncoder.h | 0 CPP/7zip/Compress/PpmdRegister.cpp | 0 CPP/7zip/Compress/PpmdZip.cpp | 0 CPP/7zip/Compress/PpmdZip.h | 0 CPP/7zip/Compress/QuantumDecoder.cpp | 0 CPP/7zip/Compress/QuantumDecoder.h | 0 CPP/7zip/Compress/Rar1Decoder.cpp | 0 CPP/7zip/Compress/Rar1Decoder.h | 0 CPP/7zip/Compress/Rar2Decoder.cpp | 0 CPP/7zip/Compress/Rar2Decoder.h | 0 CPP/7zip/Compress/Rar3Decoder.cpp | 0 CPP/7zip/Compress/Rar3Decoder.h | 0 CPP/7zip/Compress/Rar3Vm.cpp | 0 CPP/7zip/Compress/Rar3Vm.h | 0 CPP/7zip/Compress/Rar5Decoder.cpp | 0 CPP/7zip/Compress/Rar5Decoder.h | 0 CPP/7zip/Compress/RarCodecsRegister.cpp | 0 CPP/7zip/Compress/ShrinkDecoder.cpp | 0 CPP/7zip/Compress/ShrinkDecoder.h | 0 CPP/7zip/Compress/StdAfx.h | 0 CPP/7zip/Compress/XpressDecoder.cpp | 0 CPP/7zip/Compress/XpressDecoder.h | 0 CPP/7zip/Compress/XzDecoder.cpp | 0 CPP/7zip/Compress/XzDecoder.h | 0 CPP/7zip/Compress/XzEncoder.cpp | 0 CPP/7zip/Compress/XzEncoder.h | 0 CPP/7zip/Compress/ZDecoder.cpp | 0 CPP/7zip/Compress/ZDecoder.h | 0 CPP/7zip/Compress/ZlibDecoder.cpp | 0 CPP/7zip/Compress/ZlibDecoder.h | 0 CPP/7zip/Compress/ZlibEncoder.cpp | 0 CPP/7zip/Compress/ZlibEncoder.h | 0 CPP/7zip/Compress/makefile | 0 CPP/7zip/Crc.mak | 0 CPP/7zip/Crc64.mak | 0 CPP/7zip/Crypto/7zAes.cpp | 0 CPP/7zip/Crypto/7zAes.h | 0 CPP/7zip/Crypto/7zAesRegister.cpp | 0 CPP/7zip/Crypto/Codec.def | 0 CPP/7zip/Crypto/HmacSha1.cpp | 0 CPP/7zip/Crypto/HmacSha1.h | 0 CPP/7zip/Crypto/HmacSha256.cpp | 0 CPP/7zip/Crypto/HmacSha256.h | 0 CPP/7zip/Crypto/MyAes.cpp | 0 CPP/7zip/Crypto/MyAes.h | 0 CPP/7zip/Crypto/MyAesReg.cpp | 0 CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp | 0 CPP/7zip/Crypto/Pbkdf2HmacSha1.h | 0 CPP/7zip/Crypto/RandGen.cpp | 0 CPP/7zip/Crypto/RandGen.h | 0 CPP/7zip/Crypto/Rar20Crypto.cpp | 0 CPP/7zip/Crypto/Rar20Crypto.h | 0 CPP/7zip/Crypto/Rar5Aes.cpp | 0 CPP/7zip/Crypto/Rar5Aes.h | 0 CPP/7zip/Crypto/RarAes.cpp | 0 CPP/7zip/Crypto/RarAes.h | 0 CPP/7zip/Crypto/Sha1Cls.h | 0 CPP/7zip/Crypto/StdAfx.h | 0 CPP/7zip/Crypto/WzAes.cpp | 0 CPP/7zip/Crypto/WzAes.h | 0 CPP/7zip/Crypto/ZipCrypto.cpp | 0 CPP/7zip/Crypto/ZipCrypto.h | 0 CPP/7zip/Crypto/ZipStrong.cpp | 0 CPP/7zip/Crypto/ZipStrong.h | 0 CPP/7zip/GuiCommon.rc | 0 CPP/7zip/Guid.txt | 8 + CPP/7zip/ICoder.h | 0 CPP/7zip/IDecl.h | 0 CPP/7zip/IPassword.h | 0 CPP/7zip/IProgress.h | 0 CPP/7zip/IStream.h | 7 + CPP/7zip/LzFindOpt.mak | 0 CPP/7zip/LzmaDec.mak | 0 CPP/7zip/LzmaDec_gcc.mak | 0 CPP/7zip/MyVersion.h | 0 CPP/7zip/MyVersionInfo.rc | 0 CPP/7zip/PropID.h | 48 +- CPP/7zip/Sha1.mak | 0 CPP/7zip/Sha256.mak | 0 CPP/7zip/SubBuild.mak | 0 CPP/7zip/UI/Agent/Agent.cpp | 65 +- CPP/7zip/UI/Agent/Agent.h | 8 +- CPP/7zip/UI/Agent/AgentOut.cpp | 53 +- CPP/7zip/UI/Agent/AgentProxy.cpp | 101 +- CPP/7zip/UI/Agent/AgentProxy.h | 6 +- CPP/7zip/UI/Agent/ArchiveFolder.cpp | 6 + CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp | 0 CPP/7zip/UI/Agent/ArchiveFolderOut.cpp | 8 +- CPP/7zip/UI/Agent/IFolderArchive.h | 9 + CPP/7zip/UI/Agent/StdAfx.h | 0 CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp | 0 CPP/7zip/UI/Agent/UpdateCallbackAgent.h | 0 CPP/7zip/UI/Client7z/Client7z.cpp | 198 +- CPP/7zip/UI/Client7z/Client7z.dsp | 0 CPP/7zip/UI/Client7z/Client7z.dsw | 0 CPP/7zip/UI/Client7z/StdAfx.cpp | 0 CPP/7zip/UI/Client7z/StdAfx.h | 0 CPP/7zip/UI/Client7z/makefile | 0 CPP/7zip/UI/Client7z/makefile.gcc | 0 CPP/7zip/UI/Client7z/resource.rc | 0 CPP/7zip/UI/Common/ArchiveCommandLine.cpp | 36 +- CPP/7zip/UI/Common/ArchiveCommandLine.h | 7 +- CPP/7zip/UI/Common/ArchiveExtractCallback.cpp | 315 +- CPP/7zip/UI/Common/ArchiveExtractCallback.h | 97 +- CPP/7zip/UI/Common/ArchiveName.cpp | 0 CPP/7zip/UI/Common/ArchiveName.h | 0 CPP/7zip/UI/Common/ArchiveOpenCallback.cpp | 12 +- CPP/7zip/UI/Common/ArchiveOpenCallback.h | 0 CPP/7zip/UI/Common/Bench.cpp | 0 CPP/7zip/UI/Common/Bench.h | 0 CPP/7zip/UI/Common/CompressCall.cpp | 7 +- CPP/7zip/UI/Common/CompressCall.h | 2 +- CPP/7zip/UI/Common/CompressCall2.cpp | 28 +- CPP/7zip/UI/Common/DefaultName.cpp | 0 CPP/7zip/UI/Common/DefaultName.h | 0 CPP/7zip/UI/Common/DirItem.h | 249 +- CPP/7zip/UI/Common/EnumDirItems.cpp | 242 +- CPP/7zip/UI/Common/EnumDirItems.h | 0 CPP/7zip/UI/Common/ExitCode.h | 0 CPP/7zip/UI/Common/Extract.cpp | 55 +- CPP/7zip/UI/Common/Extract.h | 4 +- CPP/7zip/UI/Common/ExtractMode.h | 10 + CPP/7zip/UI/Common/ExtractingFilePath.cpp | 11 +- CPP/7zip/UI/Common/ExtractingFilePath.h | 0 CPP/7zip/UI/Common/HashCalc.cpp | 85 +- CPP/7zip/UI/Common/HashCalc.h | 6 + CPP/7zip/UI/Common/IFileExtractCallback.h | 0 CPP/7zip/UI/Common/LoadCodecs.cpp | 48 +- CPP/7zip/UI/Common/LoadCodecs.h | 40 +- CPP/7zip/UI/Common/OpenArchive.cpp | 166 +- CPP/7zip/UI/Common/OpenArchive.h | 42 +- CPP/7zip/UI/Common/PropIDUtils.cpp | 51 +- CPP/7zip/UI/Common/PropIDUtils.h | 0 CPP/7zip/UI/Common/Property.h | 0 CPP/7zip/UI/Common/SetProperties.cpp | 0 CPP/7zip/UI/Common/SetProperties.h | 0 CPP/7zip/UI/Common/SortUtils.cpp | 0 CPP/7zip/UI/Common/SortUtils.h | 0 CPP/7zip/UI/Common/StdAfx.h | 0 CPP/7zip/UI/Common/TempFiles.cpp | 0 CPP/7zip/UI/Common/TempFiles.h | 0 CPP/7zip/UI/Common/Update.cpp | 205 +- CPP/7zip/UI/Common/Update.h | 3 + CPP/7zip/UI/Common/UpdateAction.cpp | 0 CPP/7zip/UI/Common/UpdateAction.h | 0 CPP/7zip/UI/Common/UpdateCallback.cpp | 205 +- CPP/7zip/UI/Common/UpdateCallback.h | 27 +- CPP/7zip/UI/Common/UpdatePair.cpp | 125 +- CPP/7zip/UI/Common/UpdatePair.h | 0 CPP/7zip/UI/Common/UpdateProduce.cpp | 2 + CPP/7zip/UI/Common/UpdateProduce.h | 4 +- CPP/7zip/UI/Common/WorkDir.cpp | 0 CPP/7zip/UI/Common/WorkDir.h | 0 CPP/7zip/UI/Common/ZipRegistry.cpp | 105 +- CPP/7zip/UI/Common/ZipRegistry.h | 47 +- CPP/7zip/UI/Console/BenchCon.cpp | 0 CPP/7zip/UI/Console/BenchCon.h | 0 CPP/7zip/UI/Console/Console.dsp | 0 CPP/7zip/UI/Console/Console.dsw | 0 CPP/7zip/UI/Console/Console.mak | 0 CPP/7zip/UI/Console/Console.manifest | 0 CPP/7zip/UI/Console/ConsoleClose.cpp | 0 CPP/7zip/UI/Console/ConsoleClose.h | 0 .../UI/Console/ExtractCallbackConsole.cpp | 7 + CPP/7zip/UI/Console/ExtractCallbackConsole.h | 21 + CPP/7zip/UI/Console/HashCon.cpp | 0 CPP/7zip/UI/Console/HashCon.h | 0 CPP/7zip/UI/Console/List.cpp | 72 +- CPP/7zip/UI/Console/List.h | 0 CPP/7zip/UI/Console/Main.cpp | 32 +- CPP/7zip/UI/Console/MainAr.cpp | 0 CPP/7zip/UI/Console/OpenCallbackConsole.cpp | 0 CPP/7zip/UI/Console/OpenCallbackConsole.h | 0 CPP/7zip/UI/Console/PercentPrinter.cpp | 3 +- CPP/7zip/UI/Console/PercentPrinter.h | 0 CPP/7zip/UI/Console/StdAfx.cpp | 0 CPP/7zip/UI/Console/StdAfx.h | 0 CPP/7zip/UI/Console/UpdateCallbackConsole.cpp | 169 +- CPP/7zip/UI/Console/UpdateCallbackConsole.h | 5 +- CPP/7zip/UI/Console/UserInputUtils.cpp | 0 CPP/7zip/UI/Console/UserInputUtils.h | 0 CPP/7zip/UI/Console/makefile | 0 CPP/7zip/UI/Console/makefile.gcc | 0 CPP/7zip/UI/Console/resource.rc | 0 CPP/7zip/UI/Explorer/7-zip.dll.manifest | 0 CPP/7zip/UI/Explorer/ContextMenu.cpp | 5 +- CPP/7zip/UI/Explorer/ContextMenu.h | 1 + CPP/7zip/UI/Explorer/ContextMenuFlags.h | 0 CPP/7zip/UI/Explorer/DllExportsExplorer.cpp | 0 CPP/7zip/UI/Explorer/Explorer.def | 0 CPP/7zip/UI/Explorer/Explorer.dsp | 0 CPP/7zip/UI/Explorer/Explorer.dsw | 0 CPP/7zip/UI/Explorer/MenuLogo.bmp | Bin CPP/7zip/UI/Explorer/MyExplorerCommand.h | 0 CPP/7zip/UI/Explorer/MyMessages.cpp | 0 CPP/7zip/UI/Explorer/MyMessages.h | 0 CPP/7zip/UI/Explorer/RegistryContextMenu.cpp | 0 CPP/7zip/UI/Explorer/RegistryContextMenu.h | 0 CPP/7zip/UI/Explorer/StdAfx.cpp | 0 CPP/7zip/UI/Explorer/StdAfx.h | 0 CPP/7zip/UI/Explorer/makefile | 0 CPP/7zip/UI/Explorer/resource.h | 0 CPP/7zip/UI/Explorer/resource.rc | 0 CPP/7zip/UI/Explorer/resource2.rc | 0 CPP/7zip/UI/Far/ExtractEngine.cpp | 0 CPP/7zip/UI/Far/ExtractEngine.h | 0 CPP/7zip/UI/Far/Far.cpp | 0 CPP/7zip/UI/Far/Far.def | 0 CPP/7zip/UI/Far/Far.dsp | 0 CPP/7zip/UI/Far/Far.dsw | 0 CPP/7zip/UI/Far/FarPlugin.h | 0 CPP/7zip/UI/Far/FarUtils.cpp | 0 CPP/7zip/UI/Far/FarUtils.h | 0 CPP/7zip/UI/Far/Messages.h | 0 CPP/7zip/UI/Far/OverwriteDialogFar.cpp | 0 CPP/7zip/UI/Far/OverwriteDialogFar.h | 0 CPP/7zip/UI/Far/Plugin.cpp | 0 CPP/7zip/UI/Far/Plugin.h | 0 CPP/7zip/UI/Far/PluginCommon.cpp | 0 CPP/7zip/UI/Far/PluginDelete.cpp | 0 CPP/7zip/UI/Far/PluginRead.cpp | 0 CPP/7zip/UI/Far/PluginWrite.cpp | 0 CPP/7zip/UI/Far/ProgressBox.cpp | 0 CPP/7zip/UI/Far/ProgressBox.h | 0 CPP/7zip/UI/Far/StdAfx.cpp | 0 CPP/7zip/UI/Far/StdAfx.h | 0 CPP/7zip/UI/Far/UpdateCallbackFar.cpp | 0 CPP/7zip/UI/Far/UpdateCallbackFar.h | 0 CPP/7zip/UI/Far/makefile | 0 CPP/7zip/UI/Far/resource.rc | 0 CPP/7zip/UI/FileManager/7zFM.exe.manifest | 0 CPP/7zip/UI/FileManager/7zipLogo.ico | Bin CPP/7zip/UI/FileManager/AboutDialog.cpp | 0 CPP/7zip/UI/FileManager/AboutDialog.h | 0 CPP/7zip/UI/FileManager/AboutDialog.rc | 0 CPP/7zip/UI/FileManager/AboutDialogRes.h | 0 CPP/7zip/UI/FileManager/Add.bmp | Bin CPP/7zip/UI/FileManager/Add2.bmp | Bin CPP/7zip/UI/FileManager/AltStreamsFolder.cpp | 0 CPP/7zip/UI/FileManager/AltStreamsFolder.h | 0 CPP/7zip/UI/FileManager/App.cpp | 0 CPP/7zip/UI/FileManager/App.h | 0 CPP/7zip/UI/FileManager/AppState.h | 0 CPP/7zip/UI/FileManager/BrowseDialog.cpp | 0 CPP/7zip/UI/FileManager/BrowseDialog.h | 0 CPP/7zip/UI/FileManager/BrowseDialog.rc | 0 CPP/7zip/UI/FileManager/BrowseDialogRes.h | 0 CPP/7zip/UI/FileManager/ClassDefs.cpp | 0 CPP/7zip/UI/FileManager/ComboDialog.cpp | 0 CPP/7zip/UI/FileManager/ComboDialog.h | 0 CPP/7zip/UI/FileManager/ComboDialog.rc | 0 CPP/7zip/UI/FileManager/ComboDialogRes.h | 0 CPP/7zip/UI/FileManager/Copy.bmp | Bin CPP/7zip/UI/FileManager/Copy2.bmp | Bin CPP/7zip/UI/FileManager/CopyDialog.cpp | 0 CPP/7zip/UI/FileManager/CopyDialog.h | 0 CPP/7zip/UI/FileManager/CopyDialog.rc | 0 CPP/7zip/UI/FileManager/CopyDialogRes.h | 0 CPP/7zip/UI/FileManager/Delete.bmp | Bin CPP/7zip/UI/FileManager/Delete2.bmp | Bin CPP/7zip/UI/FileManager/DialogSize.h | 0 CPP/7zip/UI/FileManager/EditDialog.cpp | 0 CPP/7zip/UI/FileManager/EditDialog.h | 0 CPP/7zip/UI/FileManager/EditDialog.rc | 0 CPP/7zip/UI/FileManager/EditDialogRes.h | 0 CPP/7zip/UI/FileManager/EditPage.cpp | 0 CPP/7zip/UI/FileManager/EditPage.h | 0 CPP/7zip/UI/FileManager/EditPage.rc | 0 CPP/7zip/UI/FileManager/EditPage2.rc | 0 CPP/7zip/UI/FileManager/EditPageRes.h | 0 CPP/7zip/UI/FileManager/EnumFormatEtc.cpp | 0 CPP/7zip/UI/FileManager/EnumFormatEtc.h | 0 CPP/7zip/UI/FileManager/Extract.bmp | Bin CPP/7zip/UI/FileManager/Extract2.bmp | Bin CPP/7zip/UI/FileManager/ExtractCallback.cpp | 0 CPP/7zip/UI/FileManager/ExtractCallback.h | 0 CPP/7zip/UI/FileManager/FM.cpp | 0 CPP/7zip/UI/FileManager/FM.dsp | 0 CPP/7zip/UI/FileManager/FM.dsw | 0 CPP/7zip/UI/FileManager/FM.ico | Bin CPP/7zip/UI/FileManager/FM.mak | 0 CPP/7zip/UI/FileManager/FSDrives.cpp | 0 CPP/7zip/UI/FileManager/FSDrives.h | 0 CPP/7zip/UI/FileManager/FSFolder.cpp | 105 +- CPP/7zip/UI/FileManager/FSFolder.h | 5 + CPP/7zip/UI/FileManager/FSFolderCopy.cpp | 0 .../UI/FileManager/FileFolderPluginOpen.cpp | 0 .../UI/FileManager/FileFolderPluginOpen.h | 0 CPP/7zip/UI/FileManager/FilePlugins.cpp | 0 CPP/7zip/UI/FileManager/FilePlugins.h | 0 CPP/7zip/UI/FileManager/FoldersPage.cpp | 0 CPP/7zip/UI/FileManager/FoldersPage.h | 0 CPP/7zip/UI/FileManager/FoldersPage.rc | 0 CPP/7zip/UI/FileManager/FoldersPage2.rc | 0 CPP/7zip/UI/FileManager/FoldersPageRes.h | 0 CPP/7zip/UI/FileManager/FormatUtils.cpp | 0 CPP/7zip/UI/FileManager/FormatUtils.h | 0 CPP/7zip/UI/FileManager/HelpUtils.cpp | 42 + CPP/7zip/UI/FileManager/HelpUtils.h | 0 CPP/7zip/UI/FileManager/IFolder.h | 0 CPP/7zip/UI/FileManager/Info.bmp | Bin CPP/7zip/UI/FileManager/Info2.bmp | Bin CPP/7zip/UI/FileManager/LangPage.cpp | 0 CPP/7zip/UI/FileManager/LangPage.h | 0 CPP/7zip/UI/FileManager/LangPage.rc | 0 CPP/7zip/UI/FileManager/LangPageRes.h | 0 CPP/7zip/UI/FileManager/LangUtils.cpp | 0 CPP/7zip/UI/FileManager/LangUtils.h | 0 CPP/7zip/UI/FileManager/LinkDialog.cpp | 0 CPP/7zip/UI/FileManager/LinkDialog.h | 0 CPP/7zip/UI/FileManager/LinkDialog.rc | 0 CPP/7zip/UI/FileManager/LinkDialogRes.h | 0 CPP/7zip/UI/FileManager/ListViewDialog.cpp | 0 CPP/7zip/UI/FileManager/ListViewDialog.h | 0 CPP/7zip/UI/FileManager/ListViewDialog.rc | 0 CPP/7zip/UI/FileManager/ListViewDialogRes.h | 0 CPP/7zip/UI/FileManager/MenuPage.cpp | 76 +- CPP/7zip/UI/FileManager/MenuPage.h | 5 + CPP/7zip/UI/FileManager/MenuPage.rc | 0 CPP/7zip/UI/FileManager/MenuPage2.rc | 15 +- CPP/7zip/UI/FileManager/MenuPageRes.h | 4 + CPP/7zip/UI/FileManager/MessagesDialog.cpp | 0 CPP/7zip/UI/FileManager/MessagesDialog.h | 0 CPP/7zip/UI/FileManager/MessagesDialog.rc | 0 CPP/7zip/UI/FileManager/MessagesDialogRes.h | 0 CPP/7zip/UI/FileManager/Move.bmp | Bin CPP/7zip/UI/FileManager/Move2.bmp | Bin CPP/7zip/UI/FileManager/MyCom2.h | 0 CPP/7zip/UI/FileManager/MyLoadMenu.cpp | 3 +- CPP/7zip/UI/FileManager/MyLoadMenu.h | 0 CPP/7zip/UI/FileManager/MyWindowsNew.h | 0 CPP/7zip/UI/FileManager/NetFolder.cpp | 0 CPP/7zip/UI/FileManager/NetFolder.h | 0 CPP/7zip/UI/FileManager/OpenCallback.cpp | 0 CPP/7zip/UI/FileManager/OpenCallback.h | 0 CPP/7zip/UI/FileManager/OptionsDialog.cpp | 0 CPP/7zip/UI/FileManager/OverwriteDialog.cpp | 0 CPP/7zip/UI/FileManager/OverwriteDialog.h | 0 CPP/7zip/UI/FileManager/OverwriteDialog.rc | 0 CPP/7zip/UI/FileManager/OverwriteDialogRes.h | 0 CPP/7zip/UI/FileManager/Panel.cpp | 5 + CPP/7zip/UI/FileManager/Panel.h | 5 + CPP/7zip/UI/FileManager/PanelCopy.cpp | 21 +- CPP/7zip/UI/FileManager/PanelCrc.cpp | 1 + CPP/7zip/UI/FileManager/PanelDrag.cpp | 0 CPP/7zip/UI/FileManager/PanelFolderChange.cpp | 0 CPP/7zip/UI/FileManager/PanelItemOpen.cpp | 19 +- CPP/7zip/UI/FileManager/PanelItems.cpp | 6 +- CPP/7zip/UI/FileManager/PanelKey.cpp | 0 CPP/7zip/UI/FileManager/PanelListNotify.cpp | 0 CPP/7zip/UI/FileManager/PanelMenu.cpp | 2 +- CPP/7zip/UI/FileManager/PanelOperations.cpp | 0 CPP/7zip/UI/FileManager/PanelSelect.cpp | 0 CPP/7zip/UI/FileManager/PanelSort.cpp | 0 CPP/7zip/UI/FileManager/PanelSplitFile.cpp | 0 CPP/7zip/UI/FileManager/PasswordDialog.cpp | 0 CPP/7zip/UI/FileManager/PasswordDialog.h | 0 CPP/7zip/UI/FileManager/PasswordDialog.rc | 0 CPP/7zip/UI/FileManager/PasswordDialogRes.h | 0 CPP/7zip/UI/FileManager/PluginInterface.h | 0 CPP/7zip/UI/FileManager/PluginLoader.h | 0 CPP/7zip/UI/FileManager/ProgramLocation.cpp | 0 CPP/7zip/UI/FileManager/ProgramLocation.h | 0 CPP/7zip/UI/FileManager/ProgressDialog.cpp | 0 CPP/7zip/UI/FileManager/ProgressDialog.h | 0 CPP/7zip/UI/FileManager/ProgressDialog.rc | 0 CPP/7zip/UI/FileManager/ProgressDialog2.cpp | 0 CPP/7zip/UI/FileManager/ProgressDialog2.h | 0 CPP/7zip/UI/FileManager/ProgressDialog2.rc | 0 CPP/7zip/UI/FileManager/ProgressDialog2Res.h | 0 CPP/7zip/UI/FileManager/ProgressDialog2a.rc | 0 CPP/7zip/UI/FileManager/ProgressDialogRes.h | 0 CPP/7zip/UI/FileManager/PropertyName.cpp | 0 CPP/7zip/UI/FileManager/PropertyName.h | 0 CPP/7zip/UI/FileManager/PropertyName.rc | 7 + CPP/7zip/UI/FileManager/PropertyNameRes.h | 7 + .../UI/FileManager/RegistryAssociations.cpp | 0 .../UI/FileManager/RegistryAssociations.h | 0 CPP/7zip/UI/FileManager/RegistryPlugins.cpp | 0 CPP/7zip/UI/FileManager/RegistryPlugins.h | 0 CPP/7zip/UI/FileManager/RegistryUtils.cpp | 0 CPP/7zip/UI/FileManager/RegistryUtils.h | 0 CPP/7zip/UI/FileManager/RootFolder.cpp | 0 CPP/7zip/UI/FileManager/RootFolder.h | 0 CPP/7zip/UI/FileManager/SettingsPage.cpp | 0 CPP/7zip/UI/FileManager/SettingsPage.h | 0 CPP/7zip/UI/FileManager/SettingsPage.rc | 0 CPP/7zip/UI/FileManager/SettingsPage2.rc | 0 CPP/7zip/UI/FileManager/SettingsPageRes.h | 0 CPP/7zip/UI/FileManager/SplitDialog.cpp | 0 CPP/7zip/UI/FileManager/SplitDialog.h | 0 CPP/7zip/UI/FileManager/SplitDialog.rc | 0 CPP/7zip/UI/FileManager/SplitDialogRes.h | 0 CPP/7zip/UI/FileManager/SplitUtils.cpp | 0 CPP/7zip/UI/FileManager/SplitUtils.h | 0 CPP/7zip/UI/FileManager/StdAfx.cpp | 0 CPP/7zip/UI/FileManager/StdAfx.h | 0 CPP/7zip/UI/FileManager/StringUtils.cpp | 0 CPP/7zip/UI/FileManager/StringUtils.h | 0 CPP/7zip/UI/FileManager/SysIconUtils.cpp | 0 CPP/7zip/UI/FileManager/SysIconUtils.h | 0 CPP/7zip/UI/FileManager/SystemPage.cpp | 0 CPP/7zip/UI/FileManager/SystemPage.h | 0 CPP/7zip/UI/FileManager/SystemPage.rc | 0 CPP/7zip/UI/FileManager/SystemPageRes.h | 0 CPP/7zip/UI/FileManager/Test.bmp | Bin CPP/7zip/UI/FileManager/Test2.bmp | Bin CPP/7zip/UI/FileManager/TextPairs.cpp | 0 CPP/7zip/UI/FileManager/TextPairs.h | 0 CPP/7zip/UI/FileManager/UpdateCallback100.cpp | 0 CPP/7zip/UI/FileManager/UpdateCallback100.h | 0 CPP/7zip/UI/FileManager/VerCtrl.cpp | 0 CPP/7zip/UI/FileManager/ViewSettings.cpp | 0 CPP/7zip/UI/FileManager/ViewSettings.h | 0 CPP/7zip/UI/FileManager/makefile | 0 CPP/7zip/UI/FileManager/resource.h | 0 CPP/7zip/UI/FileManager/resource.rc | 0 CPP/7zip/UI/FileManager/resourceGui.h | 0 CPP/7zip/UI/FileManager/resourceGui.rc | 0 CPP/7zip/UI/GUI/7zG.exe.manifest | 0 CPP/7zip/UI/GUI/BenchmarkDialog.cpp | 0 CPP/7zip/UI/GUI/BenchmarkDialog.h | 0 CPP/7zip/UI/GUI/BenchmarkDialog.rc | 0 CPP/7zip/UI/GUI/BenchmarkDialogRes.h | 0 CPP/7zip/UI/GUI/CompressDialog.cpp | 724 +++- CPP/7zip/UI/GUI/CompressDialog.h | 168 +- CPP/7zip/UI/GUI/CompressDialog.rc | 27 +- CPP/7zip/UI/GUI/CompressDialogRes.h | 33 + CPP/7zip/UI/GUI/CompressOptionsDialog.rc | 76 + CPP/7zip/UI/GUI/Extract.rc | 0 CPP/7zip/UI/GUI/ExtractDialog.cpp | 0 CPP/7zip/UI/GUI/ExtractDialog.h | 0 CPP/7zip/UI/GUI/ExtractDialog.rc | 0 CPP/7zip/UI/GUI/ExtractDialogRes.h | 0 CPP/7zip/UI/GUI/ExtractGUI.cpp | 0 CPP/7zip/UI/GUI/ExtractGUI.h | 0 CPP/7zip/UI/GUI/ExtractRes.h | 0 CPP/7zip/UI/GUI/FM.ico | Bin CPP/7zip/UI/GUI/GUI.cpp | 4 +- CPP/7zip/UI/GUI/GUI.dsp | 16 + CPP/7zip/UI/GUI/GUI.dsw | 0 CPP/7zip/UI/GUI/HashGUI.cpp | 0 CPP/7zip/UI/GUI/HashGUI.h | 0 CPP/7zip/UI/GUI/StdAfx.cpp | 0 CPP/7zip/UI/GUI/StdAfx.h | 0 CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp | 0 CPP/7zip/UI/GUI/UpdateCallbackGUI.h | 0 CPP/7zip/UI/GUI/UpdateCallbackGUI2.cpp | 0 CPP/7zip/UI/GUI/UpdateCallbackGUI2.h | 0 CPP/7zip/UI/GUI/UpdateGUI.cpp | 182 +- CPP/7zip/UI/GUI/UpdateGUI.h | 0 CPP/7zip/UI/GUI/makefile | 0 CPP/7zip/UI/GUI/resource.rc | 0 CPP/7zip/UI/GUI/resource2.h | 0 CPP/7zip/UI/GUI/resource2.rc | 0 CPP/7zip/UI/GUI/resource3.h | 0 CPP/7zip/UI/GUI/resource3.rc | 0 CPP/7zip/UI/makefile | 0 CPP/7zip/cmpl_clang.mak | 0 CPP/7zip/cmpl_clang_arm64.mak | 0 CPP/7zip/cmpl_clang_x64.mak | 0 CPP/7zip/cmpl_clang_x86.mak | 0 CPP/7zip/cmpl_gcc.mak | 0 CPP/7zip/cmpl_gcc_arm64.mak | 0 CPP/7zip/cmpl_gcc_x64.mak | 0 CPP/7zip/cmpl_gcc_x86.mak | 0 CPP/7zip/cmpl_mac_arm64.mak | 0 CPP/7zip/cmpl_mac_x64.mak | 0 CPP/7zip/makefile | 0 CPP/7zip/var_clang.mak | 0 CPP/7zip/var_clang_arm64.mak | 0 CPP/7zip/var_clang_x64.mak | 0 CPP/7zip/var_clang_x86.mak | 0 CPP/7zip/var_gcc.mak | 0 CPP/7zip/var_gcc_arm64.mak | 0 CPP/7zip/var_gcc_x64.mak | 0 CPP/7zip/var_gcc_x86.mak | 0 CPP/7zip/var_mac_arm64.mak | 0 CPP/7zip/var_mac_x64.mak | 0 CPP/7zip/warn_clang.mak | 0 CPP/7zip/warn_clang_mac.mak | 0 CPP/7zip/warn_gcc.mak | 0 CPP/Build.mak | 0 CPP/Common/AutoPtr.h | 0 CPP/Common/CRC.cpp | 0 CPP/Common/C_FileIO.cpp | 0 CPP/Common/C_FileIO.h | 0 CPP/Common/CksumReg.cpp | 0 CPP/Common/ComTry.h | 0 CPP/Common/CommandLineParser.cpp | 0 CPP/Common/CommandLineParser.h | 0 CPP/Common/Common.h | 2 +- CPP/Common/CrcReg.cpp | 0 CPP/Common/Defs.h | 0 CPP/Common/DynLimBuf.cpp | 0 CPP/Common/DynLimBuf.h | 0 CPP/Common/DynamicBuffer.h | 0 CPP/Common/IntToString.cpp | 0 CPP/Common/IntToString.h | 0 CPP/Common/Lang.cpp | 0 CPP/Common/Lang.h | 0 CPP/Common/ListFileUtils.cpp | 0 CPP/Common/ListFileUtils.h | 0 CPP/Common/LzFindPrepare.cpp | 0 CPP/Common/MyBuffer.h | 0 CPP/Common/MyBuffer2.h | 0 CPP/Common/MyCom.h | 1 + CPP/Common/MyException.h | 0 CPP/Common/MyGuidDef.h | 0 CPP/Common/MyInitGuid.h | 0 CPP/Common/MyLinux.h | 33 + CPP/Common/MyMap.cpp | 0 CPP/Common/MyMap.h | 0 CPP/Common/MyString.cpp | 187 +- CPP/Common/MyString.h | 3 +- CPP/Common/MyTypes.h | 0 CPP/Common/MyUnknown.h | 0 CPP/Common/MyVector.cpp | 0 CPP/Common/MyVector.h | 215 +- CPP/Common/MyWindows.cpp | 0 CPP/Common/MyWindows.h | 2 +- CPP/Common/MyXml.cpp | 0 CPP/Common/MyXml.h | 0 CPP/Common/NewHandler.cpp | 19 +- CPP/Common/NewHandler.h | 0 CPP/Common/Random.cpp | 0 CPP/Common/Random.h | 0 CPP/Common/Sha1Prepare.cpp | 0 CPP/Common/Sha1Reg.cpp | 0 CPP/Common/Sha256Prepare.cpp | 0 CPP/Common/Sha256Reg.cpp | 0 CPP/Common/StdAfx.h | 0 CPP/Common/StdInStream.cpp | 0 CPP/Common/StdInStream.h | 0 CPP/Common/StdOutStream.cpp | 0 CPP/Common/StdOutStream.h | 0 CPP/Common/StringConvert.cpp | 0 CPP/Common/StringConvert.h | 0 CPP/Common/StringToInt.cpp | 27 + CPP/Common/StringToInt.h | 1 + CPP/Common/TextConfig.cpp | 0 CPP/Common/TextConfig.h | 0 CPP/Common/UTFConvert.cpp | 0 CPP/Common/UTFConvert.h | 0 CPP/Common/Wildcard.cpp | 0 CPP/Common/Wildcard.h | 0 CPP/Common/XzCrc64Init.cpp | 0 CPP/Common/XzCrc64Reg.cpp | 0 CPP/Windows/COM.cpp | 0 CPP/Windows/COM.h | 0 CPP/Windows/Clipboard.cpp | 0 CPP/Windows/Clipboard.h | 0 CPP/Windows/CommonDialog.cpp | 0 CPP/Windows/CommonDialog.h | 0 CPP/Windows/Console.cpp | 0 CPP/Windows/Console.h | 0 CPP/Windows/Control/ComboBox.cpp | 0 CPP/Windows/Control/ComboBox.h | 0 CPP/Windows/Control/CommandBar.h | 0 CPP/Windows/Control/Dialog.cpp | 0 CPP/Windows/Control/Dialog.h | 0 CPP/Windows/Control/Edit.h | 0 CPP/Windows/Control/ImageList.cpp | 0 CPP/Windows/Control/ImageList.h | 0 CPP/Windows/Control/ListView.cpp | 0 CPP/Windows/Control/ListView.h | 0 CPP/Windows/Control/ProgressBar.h | 0 CPP/Windows/Control/PropertyPage.cpp | 0 CPP/Windows/Control/PropertyPage.h | 0 CPP/Windows/Control/ReBar.h | 0 CPP/Windows/Control/Static.h | 0 CPP/Windows/Control/StatusBar.h | 0 CPP/Windows/Control/StdAfx.h | 0 CPP/Windows/Control/ToolBar.h | 0 CPP/Windows/Control/Trackbar.h | 0 CPP/Windows/Control/Window2.cpp | 0 CPP/Windows/Control/Window2.h | 0 CPP/Windows/DLL.cpp | 0 CPP/Windows/DLL.h | 0 CPP/Windows/Defs.h | 0 CPP/Windows/ErrorMsg.cpp | 0 CPP/Windows/ErrorMsg.h | 0 CPP/Windows/FileDir.cpp | 73 +- CPP/Windows/FileDir.h | 10 +- CPP/Windows/FileFind.cpp | 133 +- CPP/Windows/FileFind.h | 95 +- CPP/Windows/FileIO.cpp | 88 +- CPP/Windows/FileIO.h | 44 +- CPP/Windows/FileLink.cpp | 0 CPP/Windows/FileMapping.cpp | 0 CPP/Windows/FileMapping.h | 0 CPP/Windows/FileName.cpp | 0 CPP/Windows/FileName.h | 0 CPP/Windows/FileSystem.cpp | 0 CPP/Windows/FileSystem.h | 0 CPP/Windows/Handle.h | 0 CPP/Windows/MemoryGlobal.cpp | 0 CPP/Windows/MemoryGlobal.h | 0 CPP/Windows/MemoryLock.cpp | 0 CPP/Windows/MemoryLock.h | 0 CPP/Windows/Menu.cpp | 0 CPP/Windows/Menu.h | 0 CPP/Windows/NationalTime.cpp | 0 CPP/Windows/NationalTime.h | 0 CPP/Windows/Net.cpp | 0 CPP/Windows/Net.h | 0 CPP/Windows/NtCheck.h | 0 CPP/Windows/ProcessMessages.cpp | 0 CPP/Windows/ProcessMessages.h | 0 CPP/Windows/ProcessUtils.cpp | 0 CPP/Windows/ProcessUtils.h | 0 CPP/Windows/PropVariant.cpp | 132 +- CPP/Windows/PropVariant.h | 52 +- CPP/Windows/PropVariantConv.cpp | 58 +- CPP/Windows/PropVariantConv.h | 5 +- CPP/Windows/PropVariantUtils.cpp | 0 CPP/Windows/PropVariantUtils.h | 0 CPP/Windows/Registry.cpp | 0 CPP/Windows/Registry.h | 0 CPP/Windows/ResourceString.cpp | 0 CPP/Windows/ResourceString.h | 0 CPP/Windows/SecurityUtils.cpp | 2 - CPP/Windows/SecurityUtils.h | 0 CPP/Windows/Shell.cpp | 0 CPP/Windows/Shell.h | 0 CPP/Windows/StdAfx.h | 0 CPP/Windows/Synchronization.cpp | 0 CPP/Windows/Synchronization.h | 0 CPP/Windows/System.cpp | 0 CPP/Windows/System.h | 0 CPP/Windows/SystemInfo.cpp | 0 CPP/Windows/SystemInfo.h | 0 CPP/Windows/Thread.h | 0 CPP/Windows/TimeUtils.cpp | 220 +- CPP/Windows/TimeUtils.h | 130 +- CPP/Windows/Window.cpp | 0 CPP/Windows/Window.h | 0 DOC/7zC.txt | 0 DOC/7zFormat.txt | 0 DOC/7zip.hhp | 0 DOC/7zip.wxs | 4 +- DOC/License.txt | 0 DOC/Methods.txt | 0 DOC/copying.txt | 0 DOC/lzma.txt | 0 DOC/readme.txt | 0 DOC/src-history.txt | 6 + DOC/unRarLicense.txt | 0 1248 files changed, 15196 insertions(+), 2397 deletions(-) mode change 100644 => 100755 Asm/arm/7zCrcOpt.asm mode change 100644 => 100755 Asm/arm64/7zAsm.S mode change 100644 => 100755 Asm/arm64/LzmaDecOpt.S mode change 100644 => 100755 Asm/x86/7zAsm.asm mode change 100644 => 100755 Asm/x86/7zCrcOpt.asm mode change 100644 => 100755 Asm/x86/AesOpt.asm mode change 100644 => 100755 Asm/x86/LzFindOpt.asm mode change 100644 => 100755 Asm/x86/LzmaDecOpt.asm mode change 100644 => 100755 Asm/x86/Sha1Opt.asm mode change 100644 => 100755 Asm/x86/Sha256Opt.asm mode change 100644 => 100755 Asm/x86/XzCrc64Opt.asm mode change 100644 => 100755 C/7z.h mode change 100644 => 100755 C/7zAlloc.c mode change 100644 => 100755 C/7zAlloc.h mode change 100644 => 100755 C/7zArcIn.c mode change 100644 => 100755 C/7zBuf.c mode change 100644 => 100755 C/7zBuf.h mode change 100644 => 100755 C/7zBuf2.c mode change 100644 => 100755 C/7zCrc.c mode change 100644 => 100755 C/7zCrc.h mode change 100644 => 100755 C/7zCrcOpt.c mode change 100644 => 100755 C/7zDec.c mode change 100644 => 100755 C/7zFile.c mode change 100644 => 100755 C/7zFile.h mode change 100644 => 100755 C/7zStream.c mode change 100644 => 100755 C/7zTypes.h mode change 100644 => 100755 C/7zVersion.h mode change 100644 => 100755 C/7zVersion.rc mode change 100644 => 100755 C/7zip_gcc_c.mak mode change 100644 => 100755 C/Aes.c mode change 100644 => 100755 C/Aes.h mode change 100644 => 100755 C/AesOpt.c mode change 100644 => 100755 C/Alloc.c mode change 100644 => 100755 C/Alloc.h mode change 100644 => 100755 C/Bcj2.c mode change 100644 => 100755 C/Bcj2.h mode change 100644 => 100755 C/Bcj2Enc.c mode change 100644 => 100755 C/Blake2.h mode change 100644 => 100755 C/Blake2s.c mode change 100644 => 100755 C/Bra.c mode change 100644 => 100755 C/Bra.h mode change 100644 => 100755 C/Bra86.c mode change 100644 => 100755 C/BraIA64.c mode change 100644 => 100755 C/BwtSort.c mode change 100644 => 100755 C/BwtSort.h mode change 100644 => 100755 C/Compiler.h mode change 100644 => 100755 C/CpuArch.c mode change 100644 => 100755 C/CpuArch.h mode change 100644 => 100755 C/Delta.c mode change 100644 => 100755 C/Delta.h mode change 100644 => 100755 C/DllSecur.c mode change 100644 => 100755 C/DllSecur.h mode change 100644 => 100755 C/HuffEnc.c mode change 100644 => 100755 C/HuffEnc.h mode change 100644 => 100755 C/LzFind.c mode change 100644 => 100755 C/LzFind.h mode change 100644 => 100755 C/LzFindMt.c mode change 100644 => 100755 C/LzFindMt.h mode change 100644 => 100755 C/LzFindOpt.c mode change 100644 => 100755 C/LzHash.h mode change 100644 => 100755 C/Lzma2Dec.c mode change 100644 => 100755 C/Lzma2Dec.h mode change 100644 => 100755 C/Lzma2DecMt.c mode change 100644 => 100755 C/Lzma2DecMt.h mode change 100644 => 100755 C/Lzma2Enc.c mode change 100644 => 100755 C/Lzma2Enc.h mode change 100644 => 100755 C/Lzma86.h mode change 100644 => 100755 C/Lzma86Dec.c mode change 100644 => 100755 C/Lzma86Enc.c mode change 100644 => 100755 C/LzmaDec.c mode change 100644 => 100755 C/LzmaDec.h mode change 100644 => 100755 C/LzmaEnc.c mode change 100644 => 100755 C/LzmaEnc.h mode change 100644 => 100755 C/LzmaLib.c mode change 100644 => 100755 C/LzmaLib.h mode change 100644 => 100755 C/MtCoder.c mode change 100644 => 100755 C/MtCoder.h mode change 100644 => 100755 C/MtDec.c mode change 100644 => 100755 C/MtDec.h mode change 100644 => 100755 C/Ppmd.h mode change 100644 => 100755 C/Ppmd7.c mode change 100644 => 100755 C/Ppmd7.h mode change 100644 => 100755 C/Ppmd7Dec.c mode change 100644 => 100755 C/Ppmd7Enc.c mode change 100644 => 100755 C/Ppmd7aDec.c mode change 100644 => 100755 C/Ppmd8.c mode change 100644 => 100755 C/Ppmd8.h mode change 100644 => 100755 C/Ppmd8Dec.c mode change 100644 => 100755 C/Ppmd8Enc.c mode change 100644 => 100755 C/Precomp.h mode change 100644 => 100755 C/RotateDefs.h mode change 100644 => 100755 C/Sha1.c mode change 100644 => 100755 C/Sha1.h mode change 100644 => 100755 C/Sha1Opt.c mode change 100644 => 100755 C/Sha256.c mode change 100644 => 100755 C/Sha256.h mode change 100644 => 100755 C/Sha256Opt.c mode change 100644 => 100755 C/Sort.c mode change 100644 => 100755 C/Sort.h mode change 100644 => 100755 C/Threads.c mode change 100644 => 100755 C/Threads.h mode change 100644 => 100755 C/Util/7z/7z.dsp mode change 100644 => 100755 C/Util/7z/7z.dsw mode change 100644 => 100755 C/Util/7z/7zMain.c mode change 100644 => 100755 C/Util/7z/Precomp.c mode change 100644 => 100755 C/Util/7z/Precomp.h mode change 100644 => 100755 C/Util/7z/makefile mode change 100644 => 100755 C/Util/7z/makefile.gcc mode change 100644 => 100755 C/Util/7zipInstall/7zip.ico mode change 100644 => 100755 C/Util/7zipInstall/7zipInstall.c mode change 100644 => 100755 C/Util/7zipInstall/7zipInstall.dsp mode change 100644 => 100755 C/Util/7zipInstall/7zipInstall.dsw mode change 100644 => 100755 C/Util/7zipInstall/7zipInstall.manifest mode change 100644 => 100755 C/Util/7zipInstall/Precomp.c mode change 100644 => 100755 C/Util/7zipInstall/Precomp.h mode change 100644 => 100755 C/Util/7zipInstall/makefile mode change 100644 => 100755 C/Util/7zipInstall/resource.h mode change 100644 => 100755 C/Util/7zipInstall/resource.rc mode change 100644 => 100755 C/Util/7zipUninstall/7zipUninstall.c mode change 100644 => 100755 C/Util/7zipUninstall/7zipUninstall.dsp mode change 100644 => 100755 C/Util/7zipUninstall/7zipUninstall.dsw mode change 100644 => 100755 C/Util/7zipUninstall/7zipUninstall.ico mode change 100644 => 100755 C/Util/7zipUninstall/7zipUninstall.manifest mode change 100644 => 100755 C/Util/7zipUninstall/Precomp.c mode change 100644 => 100755 C/Util/7zipUninstall/Precomp.h mode change 100644 => 100755 C/Util/7zipUninstall/makefile mode change 100644 => 100755 C/Util/7zipUninstall/resource.h mode change 100644 => 100755 C/Util/7zipUninstall/resource.rc mode change 100644 => 100755 C/Util/Lzma/LzmaUtil.c mode change 100644 => 100755 C/Util/Lzma/LzmaUtil.dsp mode change 100644 => 100755 C/Util/Lzma/LzmaUtil.dsw mode change 100644 => 100755 C/Util/Lzma/makefile mode change 100644 => 100755 C/Util/Lzma/makefile.gcc mode change 100644 => 100755 C/Util/LzmaLib/LzmaLib.def mode change 100644 => 100755 C/Util/LzmaLib/LzmaLib.dsp mode change 100644 => 100755 C/Util/LzmaLib/LzmaLib.dsw mode change 100644 => 100755 C/Util/LzmaLib/LzmaLibExports.c mode change 100644 => 100755 C/Util/LzmaLib/makefile mode change 100644 => 100755 C/Util/LzmaLib/resource.rc mode change 100644 => 100755 C/Util/SfxSetup/Precomp.c mode change 100644 => 100755 C/Util/SfxSetup/Precomp.h mode change 100644 => 100755 C/Util/SfxSetup/SfxSetup.c mode change 100644 => 100755 C/Util/SfxSetup/SfxSetup.dsp mode change 100644 => 100755 C/Util/SfxSetup/SfxSetup.dsw mode change 100644 => 100755 C/Util/SfxSetup/makefile mode change 100644 => 100755 C/Util/SfxSetup/makefile_con mode change 100644 => 100755 C/Util/SfxSetup/resource.rc mode change 100644 => 100755 C/Util/SfxSetup/setup.ico mode change 100644 => 100755 C/Xz.c mode change 100644 => 100755 C/Xz.h mode change 100644 => 100755 C/XzCrc64.c mode change 100644 => 100755 C/XzCrc64.h mode change 100644 => 100755 C/XzCrc64Opt.c mode change 100644 => 100755 C/XzDec.c mode change 100644 => 100755 C/XzEnc.c mode change 100644 => 100755 C/XzEnc.h mode change 100644 => 100755 C/XzIn.c mode change 100644 => 100755 C/var_clang.mak mode change 100644 => 100755 C/var_clang_arm64.mak mode change 100644 => 100755 C/var_clang_x64.mak mode change 100644 => 100755 C/var_clang_x86.mak mode change 100644 => 100755 C/var_gcc.mak mode change 100644 => 100755 C/var_gcc_arm64.mak mode change 100644 => 100755 C/var_gcc_x64.mak mode change 100644 => 100755 C/var_gcc_x86.mak mode change 100644 => 100755 C/var_mac_arm64.mak mode change 100644 => 100755 C/var_mac_x64.mak mode change 100644 => 100755 C/warn_clang.mak mode change 100644 => 100755 C/warn_clang_mac.mak mode change 100644 => 100755 C/warn_gcc.mak mode change 100644 => 100755 CPP/7zip/7zip.mak mode change 100644 => 100755 CPP/7zip/7zip_gcc.mak mode change 100644 => 100755 CPP/7zip/Aes.mak mode change 100644 => 100755 CPP/7zip/Archive/7z/7z.dsp mode change 100644 => 100755 CPP/7zip/Archive/7z/7z.dsw mode change 100644 => 100755 CPP/7zip/Archive/7z/7zCompressionMode.cpp mode change 100644 => 100755 CPP/7zip/Archive/7z/7zCompressionMode.h mode change 100644 => 100755 CPP/7zip/Archive/7z/7zDecode.cpp mode change 100644 => 100755 CPP/7zip/Archive/7z/7zDecode.h mode change 100644 => 100755 CPP/7zip/Archive/7z/7zEncode.cpp mode change 100644 => 100755 CPP/7zip/Archive/7z/7zEncode.h mode change 100644 => 100755 CPP/7zip/Archive/7z/7zExtract.cpp mode change 100644 => 100755 CPP/7zip/Archive/7z/7zFolderInStream.cpp mode change 100644 => 100755 CPP/7zip/Archive/7z/7zFolderInStream.h mode change 100644 => 100755 CPP/7zip/Archive/7z/7zHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/7z/7zHandler.h mode change 100644 => 100755 CPP/7zip/Archive/7z/7zHandlerOut.cpp mode change 100644 => 100755 CPP/7zip/Archive/7z/7zHeader.cpp mode change 100644 => 100755 CPP/7zip/Archive/7z/7zHeader.h mode change 100644 => 100755 CPP/7zip/Archive/7z/7zIn.cpp mode change 100644 => 100755 CPP/7zip/Archive/7z/7zIn.h mode change 100644 => 100755 CPP/7zip/Archive/7z/7zItem.h mode change 100644 => 100755 CPP/7zip/Archive/7z/7zOut.cpp mode change 100644 => 100755 CPP/7zip/Archive/7z/7zOut.h mode change 100644 => 100755 CPP/7zip/Archive/7z/7zProperties.cpp mode change 100644 => 100755 CPP/7zip/Archive/7z/7zProperties.h mode change 100644 => 100755 CPP/7zip/Archive/7z/7zRegister.cpp mode change 100644 => 100755 CPP/7zip/Archive/7z/7zSpecStream.cpp mode change 100644 => 100755 CPP/7zip/Archive/7z/7zSpecStream.h mode change 100644 => 100755 CPP/7zip/Archive/7z/7zUpdate.cpp mode change 100644 => 100755 CPP/7zip/Archive/7z/7zUpdate.h mode change 100644 => 100755 CPP/7zip/Archive/7z/StdAfx.cpp mode change 100644 => 100755 CPP/7zip/Archive/7z/StdAfx.h mode change 100644 => 100755 CPP/7zip/Archive/7z/makefile mode change 100644 => 100755 CPP/7zip/Archive/7z/resource.rc create mode 100755 CPP/7zip/Archive/ApfsHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/ApmHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/ArHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/Archive.def mode change 100644 => 100755 CPP/7zip/Archive/Archive2.def mode change 100644 => 100755 CPP/7zip/Archive/ArchiveExports.cpp mode change 100644 => 100755 CPP/7zip/Archive/ArjHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/Base64Handler.cpp mode change 100644 => 100755 CPP/7zip/Archive/Bz2Handler.cpp mode change 100644 => 100755 CPP/7zip/Archive/Cab/CabBlockInStream.cpp mode change 100644 => 100755 CPP/7zip/Archive/Cab/CabBlockInStream.h mode change 100644 => 100755 CPP/7zip/Archive/Cab/CabHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/Cab/CabHandler.h mode change 100644 => 100755 CPP/7zip/Archive/Cab/CabHeader.cpp mode change 100644 => 100755 CPP/7zip/Archive/Cab/CabHeader.h mode change 100644 => 100755 CPP/7zip/Archive/Cab/CabIn.cpp mode change 100644 => 100755 CPP/7zip/Archive/Cab/CabIn.h mode change 100644 => 100755 CPP/7zip/Archive/Cab/CabItem.h mode change 100644 => 100755 CPP/7zip/Archive/Cab/CabRegister.cpp mode change 100644 => 100755 CPP/7zip/Archive/Cab/StdAfx.h mode change 100644 => 100755 CPP/7zip/Archive/Chm/ChmHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/Chm/ChmHandler.h mode change 100644 => 100755 CPP/7zip/Archive/Chm/ChmIn.cpp mode change 100644 => 100755 CPP/7zip/Archive/Chm/ChmIn.h mode change 100644 => 100755 CPP/7zip/Archive/Chm/StdAfx.h mode change 100644 => 100755 CPP/7zip/Archive/ComHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/Common/CoderMixer2.cpp mode change 100644 => 100755 CPP/7zip/Archive/Common/CoderMixer2.h mode change 100644 => 100755 CPP/7zip/Archive/Common/DummyOutStream.cpp mode change 100644 => 100755 CPP/7zip/Archive/Common/DummyOutStream.h mode change 100644 => 100755 CPP/7zip/Archive/Common/FindSignature.cpp mode change 100644 => 100755 CPP/7zip/Archive/Common/FindSignature.h mode change 100644 => 100755 CPP/7zip/Archive/Common/HandlerOut.cpp mode change 100644 => 100755 CPP/7zip/Archive/Common/HandlerOut.h mode change 100644 => 100755 CPP/7zip/Archive/Common/InStreamWithCRC.cpp mode change 100644 => 100755 CPP/7zip/Archive/Common/InStreamWithCRC.h mode change 100644 => 100755 CPP/7zip/Archive/Common/ItemNameUtils.cpp mode change 100644 => 100755 CPP/7zip/Archive/Common/ItemNameUtils.h mode change 100644 => 100755 CPP/7zip/Archive/Common/MultiStream.cpp mode change 100644 => 100755 CPP/7zip/Archive/Common/MultiStream.h mode change 100644 => 100755 CPP/7zip/Archive/Common/OutStreamWithCRC.cpp mode change 100644 => 100755 CPP/7zip/Archive/Common/OutStreamWithCRC.h mode change 100644 => 100755 CPP/7zip/Archive/Common/OutStreamWithSha1.cpp mode change 100644 => 100755 CPP/7zip/Archive/Common/OutStreamWithSha1.h mode change 100644 => 100755 CPP/7zip/Archive/Common/ParseProperties.cpp mode change 100644 => 100755 CPP/7zip/Archive/Common/ParseProperties.h mode change 100644 => 100755 CPP/7zip/Archive/Common/StdAfx.h mode change 100644 => 100755 CPP/7zip/Archive/CpioHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/CramfsHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/DeflateProps.cpp mode change 100644 => 100755 CPP/7zip/Archive/DeflateProps.h mode change 100644 => 100755 CPP/7zip/Archive/DllExports.cpp mode change 100644 => 100755 CPP/7zip/Archive/DllExports2.cpp mode change 100644 => 100755 CPP/7zip/Archive/DmgHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/ElfHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/ExtHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/FatHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/FlvHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/GptHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/GzHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/HandlerCont.cpp mode change 100644 => 100755 CPP/7zip/Archive/HandlerCont.h mode change 100644 => 100755 CPP/7zip/Archive/HfsHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/IArchive.h mode change 100644 => 100755 CPP/7zip/Archive/Icons/7z.ico create mode 100755 CPP/7zip/Archive/Icons/apfs.ico mode change 100644 => 100755 CPP/7zip/Archive/Icons/arj.ico mode change 100644 => 100755 CPP/7zip/Archive/Icons/bz2.ico mode change 100644 => 100755 CPP/7zip/Archive/Icons/cab.ico mode change 100644 => 100755 CPP/7zip/Archive/Icons/cpio.ico mode change 100644 => 100755 CPP/7zip/Archive/Icons/deb.ico mode change 100644 => 100755 CPP/7zip/Archive/Icons/dmg.ico mode change 100644 => 100755 CPP/7zip/Archive/Icons/fat.ico mode change 100644 => 100755 CPP/7zip/Archive/Icons/gz.ico mode change 100644 => 100755 CPP/7zip/Archive/Icons/hfs.ico mode change 100644 => 100755 CPP/7zip/Archive/Icons/iso.ico mode change 100644 => 100755 CPP/7zip/Archive/Icons/lzh.ico mode change 100644 => 100755 CPP/7zip/Archive/Icons/lzma.ico mode change 100644 => 100755 CPP/7zip/Archive/Icons/ntfs.ico mode change 100644 => 100755 CPP/7zip/Archive/Icons/rar.ico mode change 100644 => 100755 CPP/7zip/Archive/Icons/rpm.ico mode change 100644 => 100755 CPP/7zip/Archive/Icons/split.ico mode change 100644 => 100755 CPP/7zip/Archive/Icons/squashfs.ico mode change 100644 => 100755 CPP/7zip/Archive/Icons/tar.ico mode change 100644 => 100755 CPP/7zip/Archive/Icons/vhd.ico mode change 100644 => 100755 CPP/7zip/Archive/Icons/wim.ico mode change 100644 => 100755 CPP/7zip/Archive/Icons/xar.ico mode change 100644 => 100755 CPP/7zip/Archive/Icons/xz.ico mode change 100644 => 100755 CPP/7zip/Archive/Icons/z.ico mode change 100644 => 100755 CPP/7zip/Archive/Icons/zip.ico mode change 100644 => 100755 CPP/7zip/Archive/IhexHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/Iso/IsoHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/Iso/IsoHandler.h mode change 100644 => 100755 CPP/7zip/Archive/Iso/IsoHeader.cpp mode change 100644 => 100755 CPP/7zip/Archive/Iso/IsoHeader.h mode change 100644 => 100755 CPP/7zip/Archive/Iso/IsoIn.cpp mode change 100644 => 100755 CPP/7zip/Archive/Iso/IsoIn.h mode change 100644 => 100755 CPP/7zip/Archive/Iso/IsoItem.h mode change 100644 => 100755 CPP/7zip/Archive/Iso/IsoRegister.cpp mode change 100644 => 100755 CPP/7zip/Archive/Iso/StdAfx.h create mode 100755 CPP/7zip/Archive/LpHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/LzhHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/LzmaHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/MachoHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/MbrHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/MslzHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/MubHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/Nsis/NsisDecode.cpp mode change 100644 => 100755 CPP/7zip/Archive/Nsis/NsisDecode.h mode change 100644 => 100755 CPP/7zip/Archive/Nsis/NsisHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/Nsis/NsisHandler.h mode change 100644 => 100755 CPP/7zip/Archive/Nsis/NsisIn.cpp mode change 100644 => 100755 CPP/7zip/Archive/Nsis/NsisIn.h mode change 100644 => 100755 CPP/7zip/Archive/Nsis/NsisRegister.cpp mode change 100644 => 100755 CPP/7zip/Archive/Nsis/StdAfx.h mode change 100644 => 100755 CPP/7zip/Archive/NtfsHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/PeHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/PpmdHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/QcowHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/Rar/Rar5Handler.cpp mode change 100644 => 100755 CPP/7zip/Archive/Rar/Rar5Handler.h mode change 100644 => 100755 CPP/7zip/Archive/Rar/RarHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/Rar/RarHandler.h mode change 100644 => 100755 CPP/7zip/Archive/Rar/RarHeader.h mode change 100644 => 100755 CPP/7zip/Archive/Rar/RarItem.h mode change 100644 => 100755 CPP/7zip/Archive/Rar/RarVol.h mode change 100644 => 100755 CPP/7zip/Archive/Rar/StdAfx.cpp mode change 100644 => 100755 CPP/7zip/Archive/Rar/StdAfx.h mode change 100644 => 100755 CPP/7zip/Archive/RpmHandler.cpp create mode 100755 CPP/7zip/Archive/SparseHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/SplitHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/SquashfsHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/StdAfx.h mode change 100644 => 100755 CPP/7zip/Archive/SwfHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/Tar/StdAfx.h mode change 100644 => 100755 CPP/7zip/Archive/Tar/TarHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/Tar/TarHandler.h mode change 100644 => 100755 CPP/7zip/Archive/Tar/TarHandlerOut.cpp mode change 100644 => 100755 CPP/7zip/Archive/Tar/TarHeader.cpp mode change 100644 => 100755 CPP/7zip/Archive/Tar/TarHeader.h mode change 100644 => 100755 CPP/7zip/Archive/Tar/TarIn.cpp mode change 100644 => 100755 CPP/7zip/Archive/Tar/TarIn.h mode change 100644 => 100755 CPP/7zip/Archive/Tar/TarItem.h mode change 100644 => 100755 CPP/7zip/Archive/Tar/TarOut.cpp mode change 100644 => 100755 CPP/7zip/Archive/Tar/TarOut.h mode change 100644 => 100755 CPP/7zip/Archive/Tar/TarRegister.cpp mode change 100644 => 100755 CPP/7zip/Archive/Tar/TarUpdate.cpp mode change 100644 => 100755 CPP/7zip/Archive/Tar/TarUpdate.h mode change 100644 => 100755 CPP/7zip/Archive/Udf/StdAfx.h mode change 100644 => 100755 CPP/7zip/Archive/Udf/UdfHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/Udf/UdfHandler.h mode change 100644 => 100755 CPP/7zip/Archive/Udf/UdfIn.cpp mode change 100644 => 100755 CPP/7zip/Archive/Udf/UdfIn.h mode change 100644 => 100755 CPP/7zip/Archive/UefiHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/VdiHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/VhdHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/VhdxHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/VmdkHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/Wim/StdAfx.h mode change 100644 => 100755 CPP/7zip/Archive/Wim/WimHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/Wim/WimHandler.h mode change 100644 => 100755 CPP/7zip/Archive/Wim/WimHandlerOut.cpp mode change 100644 => 100755 CPP/7zip/Archive/Wim/WimIn.cpp mode change 100644 => 100755 CPP/7zip/Archive/Wim/WimIn.h mode change 100644 => 100755 CPP/7zip/Archive/Wim/WimRegister.cpp mode change 100644 => 100755 CPP/7zip/Archive/XarHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/XzHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/XzHandler.h mode change 100644 => 100755 CPP/7zip/Archive/ZHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/Zip/StdAfx.h mode change 100644 => 100755 CPP/7zip/Archive/Zip/ZipAddCommon.cpp mode change 100644 => 100755 CPP/7zip/Archive/Zip/ZipAddCommon.h mode change 100644 => 100755 CPP/7zip/Archive/Zip/ZipCompressionMode.h mode change 100644 => 100755 CPP/7zip/Archive/Zip/ZipHandler.cpp mode change 100644 => 100755 CPP/7zip/Archive/Zip/ZipHandler.h mode change 100644 => 100755 CPP/7zip/Archive/Zip/ZipHandlerOut.cpp mode change 100644 => 100755 CPP/7zip/Archive/Zip/ZipHeader.h mode change 100644 => 100755 CPP/7zip/Archive/Zip/ZipIn.cpp mode change 100644 => 100755 CPP/7zip/Archive/Zip/ZipIn.h mode change 100644 => 100755 CPP/7zip/Archive/Zip/ZipItem.cpp mode change 100644 => 100755 CPP/7zip/Archive/Zip/ZipItem.h mode change 100644 => 100755 CPP/7zip/Archive/Zip/ZipOut.cpp mode change 100644 => 100755 CPP/7zip/Archive/Zip/ZipOut.h mode change 100644 => 100755 CPP/7zip/Archive/Zip/ZipRegister.cpp mode change 100644 => 100755 CPP/7zip/Archive/Zip/ZipUpdate.cpp mode change 100644 => 100755 CPP/7zip/Archive/Zip/ZipUpdate.h mode change 100644 => 100755 CPP/7zip/Archive/makefile mode change 100644 => 100755 CPP/7zip/Asm.mak mode change 100644 => 100755 CPP/7zip/Bundles/Alone/Alone.dsp mode change 100644 => 100755 CPP/7zip/Bundles/Alone/Alone.dsw mode change 100644 => 100755 CPP/7zip/Bundles/Alone/StdAfx.cpp mode change 100644 => 100755 CPP/7zip/Bundles/Alone/StdAfx.h mode change 100644 => 100755 CPP/7zip/Bundles/Alone/afxres.h mode change 100644 => 100755 CPP/7zip/Bundles/Alone/makefile mode change 100644 => 100755 CPP/7zip/Bundles/Alone/makefile.gcc mode change 100644 => 100755 CPP/7zip/Bundles/Alone/resource.rc mode change 100644 => 100755 CPP/7zip/Bundles/Alone2/StdAfx.cpp mode change 100644 => 100755 CPP/7zip/Bundles/Alone2/StdAfx.h mode change 100644 => 100755 CPP/7zip/Bundles/Alone2/makefile mode change 100644 => 100755 CPP/7zip/Bundles/Alone2/makefile.gcc mode change 100644 => 100755 CPP/7zip/Bundles/Alone2/resource.rc mode change 100644 => 100755 CPP/7zip/Bundles/Alone7z/Alone.dsp mode change 100644 => 100755 CPP/7zip/Bundles/Alone7z/Alone.dsw mode change 100644 => 100755 CPP/7zip/Bundles/Alone7z/StdAfx.cpp mode change 100644 => 100755 CPP/7zip/Bundles/Alone7z/StdAfx.h mode change 100644 => 100755 CPP/7zip/Bundles/Alone7z/makefile mode change 100644 => 100755 CPP/7zip/Bundles/Alone7z/makefile.gcc mode change 100644 => 100755 CPP/7zip/Bundles/Alone7z/resource.rc mode change 100644 => 100755 CPP/7zip/Bundles/Fm/FM.dsp mode change 100644 => 100755 CPP/7zip/Bundles/Fm/FM.dsw mode change 100644 => 100755 CPP/7zip/Bundles/Fm/StdAfx.cpp mode change 100644 => 100755 CPP/7zip/Bundles/Fm/StdAfx.h mode change 100644 => 100755 CPP/7zip/Bundles/Fm/makefile mode change 100644 => 100755 CPP/7zip/Bundles/Fm/resource.rc mode change 100644 => 100755 CPP/7zip/Bundles/Format7z/StdAfx.cpp mode change 100644 => 100755 CPP/7zip/Bundles/Format7z/StdAfx.h mode change 100644 => 100755 CPP/7zip/Bundles/Format7z/makefile mode change 100644 => 100755 CPP/7zip/Bundles/Format7z/resource.rc mode change 100644 => 100755 CPP/7zip/Bundles/Format7zExtract/StdAfx.cpp mode change 100644 => 100755 CPP/7zip/Bundles/Format7zExtract/StdAfx.h mode change 100644 => 100755 CPP/7zip/Bundles/Format7zExtract/makefile mode change 100644 => 100755 CPP/7zip/Bundles/Format7zExtract/resource.rc mode change 100644 => 100755 CPP/7zip/Bundles/Format7zExtractR/StdAfx.cpp mode change 100644 => 100755 CPP/7zip/Bundles/Format7zExtractR/StdAfx.h mode change 100644 => 100755 CPP/7zip/Bundles/Format7zExtractR/makefile mode change 100644 => 100755 CPP/7zip/Bundles/Format7zExtractR/resource.rc mode change 100644 => 100755 CPP/7zip/Bundles/Format7zF/Arc.mak mode change 100644 => 100755 CPP/7zip/Bundles/Format7zF/Arc_gcc.mak mode change 100644 => 100755 CPP/7zip/Bundles/Format7zF/Format7z.dsp mode change 100644 => 100755 CPP/7zip/Bundles/Format7zF/Format7z.dsw mode change 100644 => 100755 CPP/7zip/Bundles/Format7zF/StdAfx.cpp mode change 100644 => 100755 CPP/7zip/Bundles/Format7zF/StdAfx.h mode change 100644 => 100755 CPP/7zip/Bundles/Format7zF/makefile mode change 100644 => 100755 CPP/7zip/Bundles/Format7zF/makefile.gcc mode change 100644 => 100755 CPP/7zip/Bundles/Format7zF/resource.rc mode change 100644 => 100755 CPP/7zip/Bundles/Format7zR/StdAfx.cpp mode change 100644 => 100755 CPP/7zip/Bundles/Format7zR/StdAfx.h mode change 100644 => 100755 CPP/7zip/Bundles/Format7zR/makefile mode change 100644 => 100755 CPP/7zip/Bundles/Format7zR/resource.rc mode change 100644 => 100755 CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp mode change 100644 => 100755 CPP/7zip/Bundles/LzmaCon/LzmaCon.dsp mode change 100644 => 100755 CPP/7zip/Bundles/LzmaCon/LzmaCon.dsw mode change 100644 => 100755 CPP/7zip/Bundles/LzmaCon/StdAfx.cpp mode change 100644 => 100755 CPP/7zip/Bundles/LzmaCon/StdAfx.h mode change 100644 => 100755 CPP/7zip/Bundles/LzmaCon/makefile mode change 100644 => 100755 CPP/7zip/Bundles/LzmaCon/makefile.gcc mode change 100644 => 100755 CPP/7zip/Bundles/LzmaCon/resource.rc mode change 100644 => 100755 CPP/7zip/Bundles/SFXCon/7z.ico mode change 100644 => 100755 CPP/7zip/Bundles/SFXCon/SFXCon.dsp mode change 100644 => 100755 CPP/7zip/Bundles/SFXCon/SFXCon.dsw mode change 100644 => 100755 CPP/7zip/Bundles/SFXCon/SfxCon.cpp mode change 100644 => 100755 CPP/7zip/Bundles/SFXCon/StdAfx.cpp mode change 100644 => 100755 CPP/7zip/Bundles/SFXCon/StdAfx.h mode change 100644 => 100755 CPP/7zip/Bundles/SFXCon/makefile mode change 100644 => 100755 CPP/7zip/Bundles/SFXCon/makefile.gcc mode change 100644 => 100755 CPP/7zip/Bundles/SFXCon/resource.rc mode change 100644 => 100755 CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp mode change 100644 => 100755 CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.h mode change 100644 => 100755 CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp mode change 100644 => 100755 CPP/7zip/Bundles/SFXSetup/ExtractEngine.h mode change 100644 => 100755 CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp mode change 100644 => 100755 CPP/7zip/Bundles/SFXSetup/SFXSetup.dsw mode change 100644 => 100755 CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp mode change 100644 => 100755 CPP/7zip/Bundles/SFXSetup/StdAfx.cpp mode change 100644 => 100755 CPP/7zip/Bundles/SFXSetup/StdAfx.h mode change 100644 => 100755 CPP/7zip/Bundles/SFXSetup/makefile mode change 100644 => 100755 CPP/7zip/Bundles/SFXSetup/resource.h mode change 100644 => 100755 CPP/7zip/Bundles/SFXSetup/resource.rc mode change 100644 => 100755 CPP/7zip/Bundles/SFXSetup/setup.ico mode change 100644 => 100755 CPP/7zip/Bundles/SFXWin/7z.ico mode change 100644 => 100755 CPP/7zip/Bundles/SFXWin/SFXWin.dsp mode change 100644 => 100755 CPP/7zip/Bundles/SFXWin/SFXWin.dsw mode change 100644 => 100755 CPP/7zip/Bundles/SFXWin/SfxWin.cpp mode change 100644 => 100755 CPP/7zip/Bundles/SFXWin/StdAfx.cpp mode change 100644 => 100755 CPP/7zip/Bundles/SFXWin/StdAfx.h mode change 100644 => 100755 CPP/7zip/Bundles/SFXWin/makefile mode change 100644 => 100755 CPP/7zip/Bundles/SFXWin/resource.h mode change 100644 => 100755 CPP/7zip/Bundles/SFXWin/resource.rc mode change 100644 => 100755 CPP/7zip/Bundles/makefile mode change 100644 => 100755 CPP/7zip/Common/CWrappers.cpp mode change 100644 => 100755 CPP/7zip/Common/CWrappers.h mode change 100644 => 100755 CPP/7zip/Common/CreateCoder.cpp mode change 100644 => 100755 CPP/7zip/Common/CreateCoder.h mode change 100644 => 100755 CPP/7zip/Common/FilePathAutoRename.cpp mode change 100644 => 100755 CPP/7zip/Common/FilePathAutoRename.h mode change 100644 => 100755 CPP/7zip/Common/FileStreams.cpp mode change 100644 => 100755 CPP/7zip/Common/FileStreams.h mode change 100644 => 100755 CPP/7zip/Common/FilterCoder.cpp mode change 100644 => 100755 CPP/7zip/Common/FilterCoder.h mode change 100644 => 100755 CPP/7zip/Common/InBuffer.cpp mode change 100644 => 100755 CPP/7zip/Common/InBuffer.h mode change 100644 => 100755 CPP/7zip/Common/InOutTempBuffer.cpp mode change 100644 => 100755 CPP/7zip/Common/InOutTempBuffer.h mode change 100644 => 100755 CPP/7zip/Common/LimitedStreams.cpp mode change 100644 => 100755 CPP/7zip/Common/LimitedStreams.h mode change 100644 => 100755 CPP/7zip/Common/LockedStream.cpp mode change 100644 => 100755 CPP/7zip/Common/LockedStream.h mode change 100644 => 100755 CPP/7zip/Common/MemBlocks.cpp mode change 100644 => 100755 CPP/7zip/Common/MemBlocks.h mode change 100644 => 100755 CPP/7zip/Common/MethodId.cpp mode change 100644 => 100755 CPP/7zip/Common/MethodId.h mode change 100644 => 100755 CPP/7zip/Common/MethodProps.cpp mode change 100644 => 100755 CPP/7zip/Common/MethodProps.h mode change 100644 => 100755 CPP/7zip/Common/OffsetStream.cpp mode change 100644 => 100755 CPP/7zip/Common/OffsetStream.h mode change 100644 => 100755 CPP/7zip/Common/OutBuffer.cpp mode change 100644 => 100755 CPP/7zip/Common/OutBuffer.h mode change 100644 => 100755 CPP/7zip/Common/OutMemStream.cpp mode change 100644 => 100755 CPP/7zip/Common/OutMemStream.h mode change 100644 => 100755 CPP/7zip/Common/ProgressMt.cpp mode change 100644 => 100755 CPP/7zip/Common/ProgressMt.h mode change 100644 => 100755 CPP/7zip/Common/ProgressUtils.cpp mode change 100644 => 100755 CPP/7zip/Common/ProgressUtils.h mode change 100644 => 100755 CPP/7zip/Common/PropId.cpp mode change 100644 => 100755 CPP/7zip/Common/RegisterArc.h mode change 100644 => 100755 CPP/7zip/Common/RegisterCodec.h mode change 100644 => 100755 CPP/7zip/Common/StdAfx.h mode change 100644 => 100755 CPP/7zip/Common/StreamBinder.cpp mode change 100644 => 100755 CPP/7zip/Common/StreamBinder.h mode change 100644 => 100755 CPP/7zip/Common/StreamObjects.cpp mode change 100644 => 100755 CPP/7zip/Common/StreamObjects.h mode change 100644 => 100755 CPP/7zip/Common/StreamUtils.cpp mode change 100644 => 100755 CPP/7zip/Common/StreamUtils.h mode change 100644 => 100755 CPP/7zip/Common/UniqBlocks.cpp mode change 100644 => 100755 CPP/7zip/Common/UniqBlocks.h mode change 100644 => 100755 CPP/7zip/Common/VirtThread.cpp mode change 100644 => 100755 CPP/7zip/Common/VirtThread.h mode change 100644 => 100755 CPP/7zip/Compress/BZip2Const.h mode change 100644 => 100755 CPP/7zip/Compress/BZip2Crc.cpp mode change 100644 => 100755 CPP/7zip/Compress/BZip2Crc.h mode change 100644 => 100755 CPP/7zip/Compress/BZip2Decoder.cpp mode change 100644 => 100755 CPP/7zip/Compress/BZip2Decoder.h mode change 100644 => 100755 CPP/7zip/Compress/BZip2Encoder.cpp mode change 100644 => 100755 CPP/7zip/Compress/BZip2Encoder.h mode change 100644 => 100755 CPP/7zip/Compress/BZip2Register.cpp mode change 100644 => 100755 CPP/7zip/Compress/Bcj2Coder.cpp mode change 100644 => 100755 CPP/7zip/Compress/Bcj2Coder.h mode change 100644 => 100755 CPP/7zip/Compress/Bcj2Register.cpp mode change 100644 => 100755 CPP/7zip/Compress/BcjCoder.cpp mode change 100644 => 100755 CPP/7zip/Compress/BcjCoder.h mode change 100644 => 100755 CPP/7zip/Compress/BcjRegister.cpp mode change 100644 => 100755 CPP/7zip/Compress/BitlDecoder.cpp mode change 100644 => 100755 CPP/7zip/Compress/BitlDecoder.h mode change 100644 => 100755 CPP/7zip/Compress/BitlEncoder.h mode change 100644 => 100755 CPP/7zip/Compress/BitmDecoder.h mode change 100644 => 100755 CPP/7zip/Compress/BitmEncoder.h mode change 100644 => 100755 CPP/7zip/Compress/BranchMisc.cpp mode change 100644 => 100755 CPP/7zip/Compress/BranchMisc.h mode change 100644 => 100755 CPP/7zip/Compress/BranchRegister.cpp mode change 100644 => 100755 CPP/7zip/Compress/ByteSwap.cpp mode change 100644 => 100755 CPP/7zip/Compress/Codec.def mode change 100644 => 100755 CPP/7zip/Compress/CodecExports.cpp mode change 100644 => 100755 CPP/7zip/Compress/CopyCoder.cpp mode change 100644 => 100755 CPP/7zip/Compress/CopyCoder.h mode change 100644 => 100755 CPP/7zip/Compress/CopyRegister.cpp mode change 100644 => 100755 CPP/7zip/Compress/Deflate64Register.cpp mode change 100644 => 100755 CPP/7zip/Compress/DeflateConst.h mode change 100644 => 100755 CPP/7zip/Compress/DeflateDecoder.cpp mode change 100644 => 100755 CPP/7zip/Compress/DeflateDecoder.h mode change 100644 => 100755 CPP/7zip/Compress/DeflateEncoder.cpp mode change 100644 => 100755 CPP/7zip/Compress/DeflateEncoder.h mode change 100644 => 100755 CPP/7zip/Compress/DeflateRegister.cpp mode change 100644 => 100755 CPP/7zip/Compress/DeltaFilter.cpp mode change 100644 => 100755 CPP/7zip/Compress/DllExports2Compress.cpp mode change 100644 => 100755 CPP/7zip/Compress/DllExportsCompress.cpp mode change 100644 => 100755 CPP/7zip/Compress/HuffmanDecoder.h mode change 100644 => 100755 CPP/7zip/Compress/ImplodeDecoder.cpp mode change 100644 => 100755 CPP/7zip/Compress/ImplodeDecoder.h mode change 100644 => 100755 CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp mode change 100644 => 100755 CPP/7zip/Compress/ImplodeHuffmanDecoder.h mode change 100644 => 100755 CPP/7zip/Compress/LzOutWindow.cpp mode change 100644 => 100755 CPP/7zip/Compress/LzOutWindow.h mode change 100644 => 100755 CPP/7zip/Compress/LzfseDecoder.cpp mode change 100644 => 100755 CPP/7zip/Compress/LzfseDecoder.h mode change 100644 => 100755 CPP/7zip/Compress/LzhDecoder.cpp mode change 100644 => 100755 CPP/7zip/Compress/LzhDecoder.h mode change 100644 => 100755 CPP/7zip/Compress/Lzma2Decoder.cpp mode change 100644 => 100755 CPP/7zip/Compress/Lzma2Decoder.h mode change 100644 => 100755 CPP/7zip/Compress/Lzma2Encoder.cpp mode change 100644 => 100755 CPP/7zip/Compress/Lzma2Encoder.h mode change 100644 => 100755 CPP/7zip/Compress/Lzma2Register.cpp mode change 100644 => 100755 CPP/7zip/Compress/LzmaDecoder.cpp mode change 100644 => 100755 CPP/7zip/Compress/LzmaDecoder.h mode change 100644 => 100755 CPP/7zip/Compress/LzmaEncoder.cpp mode change 100644 => 100755 CPP/7zip/Compress/LzmaEncoder.h mode change 100644 => 100755 CPP/7zip/Compress/LzmaRegister.cpp mode change 100644 => 100755 CPP/7zip/Compress/LzmsDecoder.cpp mode change 100644 => 100755 CPP/7zip/Compress/LzmsDecoder.h mode change 100644 => 100755 CPP/7zip/Compress/Lzx.h mode change 100644 => 100755 CPP/7zip/Compress/LzxDecoder.cpp mode change 100644 => 100755 CPP/7zip/Compress/LzxDecoder.h mode change 100644 => 100755 CPP/7zip/Compress/Mtf8.h mode change 100644 => 100755 CPP/7zip/Compress/PpmdDecoder.cpp mode change 100644 => 100755 CPP/7zip/Compress/PpmdDecoder.h mode change 100644 => 100755 CPP/7zip/Compress/PpmdEncoder.cpp mode change 100644 => 100755 CPP/7zip/Compress/PpmdEncoder.h mode change 100644 => 100755 CPP/7zip/Compress/PpmdRegister.cpp mode change 100644 => 100755 CPP/7zip/Compress/PpmdZip.cpp mode change 100644 => 100755 CPP/7zip/Compress/PpmdZip.h mode change 100644 => 100755 CPP/7zip/Compress/QuantumDecoder.cpp mode change 100644 => 100755 CPP/7zip/Compress/QuantumDecoder.h mode change 100644 => 100755 CPP/7zip/Compress/Rar1Decoder.cpp mode change 100644 => 100755 CPP/7zip/Compress/Rar1Decoder.h mode change 100644 => 100755 CPP/7zip/Compress/Rar2Decoder.cpp mode change 100644 => 100755 CPP/7zip/Compress/Rar2Decoder.h mode change 100644 => 100755 CPP/7zip/Compress/Rar3Decoder.cpp mode change 100644 => 100755 CPP/7zip/Compress/Rar3Decoder.h mode change 100644 => 100755 CPP/7zip/Compress/Rar3Vm.cpp mode change 100644 => 100755 CPP/7zip/Compress/Rar3Vm.h mode change 100644 => 100755 CPP/7zip/Compress/Rar5Decoder.cpp mode change 100644 => 100755 CPP/7zip/Compress/Rar5Decoder.h mode change 100644 => 100755 CPP/7zip/Compress/RarCodecsRegister.cpp mode change 100644 => 100755 CPP/7zip/Compress/ShrinkDecoder.cpp mode change 100644 => 100755 CPP/7zip/Compress/ShrinkDecoder.h mode change 100644 => 100755 CPP/7zip/Compress/StdAfx.h mode change 100644 => 100755 CPP/7zip/Compress/XpressDecoder.cpp mode change 100644 => 100755 CPP/7zip/Compress/XpressDecoder.h mode change 100644 => 100755 CPP/7zip/Compress/XzDecoder.cpp mode change 100644 => 100755 CPP/7zip/Compress/XzDecoder.h mode change 100644 => 100755 CPP/7zip/Compress/XzEncoder.cpp mode change 100644 => 100755 CPP/7zip/Compress/XzEncoder.h mode change 100644 => 100755 CPP/7zip/Compress/ZDecoder.cpp mode change 100644 => 100755 CPP/7zip/Compress/ZDecoder.h mode change 100644 => 100755 CPP/7zip/Compress/ZlibDecoder.cpp mode change 100644 => 100755 CPP/7zip/Compress/ZlibDecoder.h mode change 100644 => 100755 CPP/7zip/Compress/ZlibEncoder.cpp mode change 100644 => 100755 CPP/7zip/Compress/ZlibEncoder.h mode change 100644 => 100755 CPP/7zip/Compress/makefile mode change 100644 => 100755 CPP/7zip/Crc.mak mode change 100644 => 100755 CPP/7zip/Crc64.mak mode change 100644 => 100755 CPP/7zip/Crypto/7zAes.cpp mode change 100644 => 100755 CPP/7zip/Crypto/7zAes.h mode change 100644 => 100755 CPP/7zip/Crypto/7zAesRegister.cpp mode change 100644 => 100755 CPP/7zip/Crypto/Codec.def mode change 100644 => 100755 CPP/7zip/Crypto/HmacSha1.cpp mode change 100644 => 100755 CPP/7zip/Crypto/HmacSha1.h mode change 100644 => 100755 CPP/7zip/Crypto/HmacSha256.cpp mode change 100644 => 100755 CPP/7zip/Crypto/HmacSha256.h mode change 100644 => 100755 CPP/7zip/Crypto/MyAes.cpp mode change 100644 => 100755 CPP/7zip/Crypto/MyAes.h mode change 100644 => 100755 CPP/7zip/Crypto/MyAesReg.cpp mode change 100644 => 100755 CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp mode change 100644 => 100755 CPP/7zip/Crypto/Pbkdf2HmacSha1.h mode change 100644 => 100755 CPP/7zip/Crypto/RandGen.cpp mode change 100644 => 100755 CPP/7zip/Crypto/RandGen.h mode change 100644 => 100755 CPP/7zip/Crypto/Rar20Crypto.cpp mode change 100644 => 100755 CPP/7zip/Crypto/Rar20Crypto.h mode change 100644 => 100755 CPP/7zip/Crypto/Rar5Aes.cpp mode change 100644 => 100755 CPP/7zip/Crypto/Rar5Aes.h mode change 100644 => 100755 CPP/7zip/Crypto/RarAes.cpp mode change 100644 => 100755 CPP/7zip/Crypto/RarAes.h mode change 100644 => 100755 CPP/7zip/Crypto/Sha1Cls.h mode change 100644 => 100755 CPP/7zip/Crypto/StdAfx.h mode change 100644 => 100755 CPP/7zip/Crypto/WzAes.cpp mode change 100644 => 100755 CPP/7zip/Crypto/WzAes.h mode change 100644 => 100755 CPP/7zip/Crypto/ZipCrypto.cpp mode change 100644 => 100755 CPP/7zip/Crypto/ZipCrypto.h mode change 100644 => 100755 CPP/7zip/Crypto/ZipStrong.cpp mode change 100644 => 100755 CPP/7zip/Crypto/ZipStrong.h mode change 100644 => 100755 CPP/7zip/GuiCommon.rc mode change 100644 => 100755 CPP/7zip/Guid.txt mode change 100644 => 100755 CPP/7zip/ICoder.h mode change 100644 => 100755 CPP/7zip/IDecl.h mode change 100644 => 100755 CPP/7zip/IPassword.h mode change 100644 => 100755 CPP/7zip/IProgress.h mode change 100644 => 100755 CPP/7zip/IStream.h mode change 100644 => 100755 CPP/7zip/LzFindOpt.mak mode change 100644 => 100755 CPP/7zip/LzmaDec.mak mode change 100644 => 100755 CPP/7zip/LzmaDec_gcc.mak mode change 100644 => 100755 CPP/7zip/MyVersion.h mode change 100644 => 100755 CPP/7zip/MyVersionInfo.rc mode change 100644 => 100755 CPP/7zip/PropID.h mode change 100644 => 100755 CPP/7zip/Sha1.mak mode change 100644 => 100755 CPP/7zip/Sha256.mak mode change 100644 => 100755 CPP/7zip/SubBuild.mak mode change 100644 => 100755 CPP/7zip/UI/Agent/Agent.cpp mode change 100644 => 100755 CPP/7zip/UI/Agent/Agent.h mode change 100644 => 100755 CPP/7zip/UI/Agent/AgentOut.cpp mode change 100644 => 100755 CPP/7zip/UI/Agent/AgentProxy.cpp mode change 100644 => 100755 CPP/7zip/UI/Agent/AgentProxy.h mode change 100644 => 100755 CPP/7zip/UI/Agent/ArchiveFolder.cpp mode change 100644 => 100755 CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp mode change 100644 => 100755 CPP/7zip/UI/Agent/ArchiveFolderOut.cpp mode change 100644 => 100755 CPP/7zip/UI/Agent/IFolderArchive.h mode change 100644 => 100755 CPP/7zip/UI/Agent/StdAfx.h mode change 100644 => 100755 CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp mode change 100644 => 100755 CPP/7zip/UI/Agent/UpdateCallbackAgent.h mode change 100644 => 100755 CPP/7zip/UI/Client7z/Client7z.cpp mode change 100644 => 100755 CPP/7zip/UI/Client7z/Client7z.dsp mode change 100644 => 100755 CPP/7zip/UI/Client7z/Client7z.dsw mode change 100644 => 100755 CPP/7zip/UI/Client7z/StdAfx.cpp mode change 100644 => 100755 CPP/7zip/UI/Client7z/StdAfx.h mode change 100644 => 100755 CPP/7zip/UI/Client7z/makefile mode change 100644 => 100755 CPP/7zip/UI/Client7z/makefile.gcc mode change 100644 => 100755 CPP/7zip/UI/Client7z/resource.rc mode change 100644 => 100755 CPP/7zip/UI/Common/ArchiveCommandLine.cpp mode change 100644 => 100755 CPP/7zip/UI/Common/ArchiveCommandLine.h mode change 100644 => 100755 CPP/7zip/UI/Common/ArchiveExtractCallback.cpp mode change 100644 => 100755 CPP/7zip/UI/Common/ArchiveExtractCallback.h mode change 100644 => 100755 CPP/7zip/UI/Common/ArchiveName.cpp mode change 100644 => 100755 CPP/7zip/UI/Common/ArchiveName.h mode change 100644 => 100755 CPP/7zip/UI/Common/ArchiveOpenCallback.cpp mode change 100644 => 100755 CPP/7zip/UI/Common/ArchiveOpenCallback.h mode change 100644 => 100755 CPP/7zip/UI/Common/Bench.cpp mode change 100644 => 100755 CPP/7zip/UI/Common/Bench.h mode change 100644 => 100755 CPP/7zip/UI/Common/CompressCall.cpp mode change 100644 => 100755 CPP/7zip/UI/Common/CompressCall.h mode change 100644 => 100755 CPP/7zip/UI/Common/CompressCall2.cpp mode change 100644 => 100755 CPP/7zip/UI/Common/DefaultName.cpp mode change 100644 => 100755 CPP/7zip/UI/Common/DefaultName.h mode change 100644 => 100755 CPP/7zip/UI/Common/DirItem.h mode change 100644 => 100755 CPP/7zip/UI/Common/EnumDirItems.cpp mode change 100644 => 100755 CPP/7zip/UI/Common/EnumDirItems.h mode change 100644 => 100755 CPP/7zip/UI/Common/ExitCode.h mode change 100644 => 100755 CPP/7zip/UI/Common/Extract.cpp mode change 100644 => 100755 CPP/7zip/UI/Common/Extract.h mode change 100644 => 100755 CPP/7zip/UI/Common/ExtractMode.h mode change 100644 => 100755 CPP/7zip/UI/Common/ExtractingFilePath.cpp mode change 100644 => 100755 CPP/7zip/UI/Common/ExtractingFilePath.h mode change 100644 => 100755 CPP/7zip/UI/Common/HashCalc.cpp mode change 100644 => 100755 CPP/7zip/UI/Common/HashCalc.h mode change 100644 => 100755 CPP/7zip/UI/Common/IFileExtractCallback.h mode change 100644 => 100755 CPP/7zip/UI/Common/LoadCodecs.cpp mode change 100644 => 100755 CPP/7zip/UI/Common/LoadCodecs.h mode change 100644 => 100755 CPP/7zip/UI/Common/OpenArchive.cpp mode change 100644 => 100755 CPP/7zip/UI/Common/OpenArchive.h mode change 100644 => 100755 CPP/7zip/UI/Common/PropIDUtils.cpp mode change 100644 => 100755 CPP/7zip/UI/Common/PropIDUtils.h mode change 100644 => 100755 CPP/7zip/UI/Common/Property.h mode change 100644 => 100755 CPP/7zip/UI/Common/SetProperties.cpp mode change 100644 => 100755 CPP/7zip/UI/Common/SetProperties.h mode change 100644 => 100755 CPP/7zip/UI/Common/SortUtils.cpp mode change 100644 => 100755 CPP/7zip/UI/Common/SortUtils.h mode change 100644 => 100755 CPP/7zip/UI/Common/StdAfx.h mode change 100644 => 100755 CPP/7zip/UI/Common/TempFiles.cpp mode change 100644 => 100755 CPP/7zip/UI/Common/TempFiles.h mode change 100644 => 100755 CPP/7zip/UI/Common/Update.cpp mode change 100644 => 100755 CPP/7zip/UI/Common/Update.h mode change 100644 => 100755 CPP/7zip/UI/Common/UpdateAction.cpp mode change 100644 => 100755 CPP/7zip/UI/Common/UpdateAction.h mode change 100644 => 100755 CPP/7zip/UI/Common/UpdateCallback.cpp mode change 100644 => 100755 CPP/7zip/UI/Common/UpdateCallback.h mode change 100644 => 100755 CPP/7zip/UI/Common/UpdatePair.cpp mode change 100644 => 100755 CPP/7zip/UI/Common/UpdatePair.h mode change 100644 => 100755 CPP/7zip/UI/Common/UpdateProduce.cpp mode change 100644 => 100755 CPP/7zip/UI/Common/UpdateProduce.h mode change 100644 => 100755 CPP/7zip/UI/Common/WorkDir.cpp mode change 100644 => 100755 CPP/7zip/UI/Common/WorkDir.h mode change 100644 => 100755 CPP/7zip/UI/Common/ZipRegistry.cpp mode change 100644 => 100755 CPP/7zip/UI/Common/ZipRegistry.h mode change 100644 => 100755 CPP/7zip/UI/Console/BenchCon.cpp mode change 100644 => 100755 CPP/7zip/UI/Console/BenchCon.h mode change 100644 => 100755 CPP/7zip/UI/Console/Console.dsp mode change 100644 => 100755 CPP/7zip/UI/Console/Console.dsw mode change 100644 => 100755 CPP/7zip/UI/Console/Console.mak mode change 100644 => 100755 CPP/7zip/UI/Console/Console.manifest mode change 100644 => 100755 CPP/7zip/UI/Console/ConsoleClose.cpp mode change 100644 => 100755 CPP/7zip/UI/Console/ConsoleClose.h mode change 100644 => 100755 CPP/7zip/UI/Console/ExtractCallbackConsole.cpp mode change 100644 => 100755 CPP/7zip/UI/Console/ExtractCallbackConsole.h mode change 100644 => 100755 CPP/7zip/UI/Console/HashCon.cpp mode change 100644 => 100755 CPP/7zip/UI/Console/HashCon.h mode change 100644 => 100755 CPP/7zip/UI/Console/List.cpp mode change 100644 => 100755 CPP/7zip/UI/Console/List.h mode change 100644 => 100755 CPP/7zip/UI/Console/Main.cpp mode change 100644 => 100755 CPP/7zip/UI/Console/MainAr.cpp mode change 100644 => 100755 CPP/7zip/UI/Console/OpenCallbackConsole.cpp mode change 100644 => 100755 CPP/7zip/UI/Console/OpenCallbackConsole.h mode change 100644 => 100755 CPP/7zip/UI/Console/PercentPrinter.cpp mode change 100644 => 100755 CPP/7zip/UI/Console/PercentPrinter.h mode change 100644 => 100755 CPP/7zip/UI/Console/StdAfx.cpp mode change 100644 => 100755 CPP/7zip/UI/Console/StdAfx.h mode change 100644 => 100755 CPP/7zip/UI/Console/UpdateCallbackConsole.cpp mode change 100644 => 100755 CPP/7zip/UI/Console/UpdateCallbackConsole.h mode change 100644 => 100755 CPP/7zip/UI/Console/UserInputUtils.cpp mode change 100644 => 100755 CPP/7zip/UI/Console/UserInputUtils.h mode change 100644 => 100755 CPP/7zip/UI/Console/makefile mode change 100644 => 100755 CPP/7zip/UI/Console/makefile.gcc mode change 100644 => 100755 CPP/7zip/UI/Console/resource.rc mode change 100644 => 100755 CPP/7zip/UI/Explorer/7-zip.dll.manifest mode change 100644 => 100755 CPP/7zip/UI/Explorer/ContextMenu.cpp mode change 100644 => 100755 CPP/7zip/UI/Explorer/ContextMenu.h mode change 100644 => 100755 CPP/7zip/UI/Explorer/ContextMenuFlags.h mode change 100644 => 100755 CPP/7zip/UI/Explorer/DllExportsExplorer.cpp mode change 100644 => 100755 CPP/7zip/UI/Explorer/Explorer.def mode change 100644 => 100755 CPP/7zip/UI/Explorer/Explorer.dsp mode change 100644 => 100755 CPP/7zip/UI/Explorer/Explorer.dsw mode change 100644 => 100755 CPP/7zip/UI/Explorer/MenuLogo.bmp mode change 100644 => 100755 CPP/7zip/UI/Explorer/MyExplorerCommand.h mode change 100644 => 100755 CPP/7zip/UI/Explorer/MyMessages.cpp mode change 100644 => 100755 CPP/7zip/UI/Explorer/MyMessages.h mode change 100644 => 100755 CPP/7zip/UI/Explorer/RegistryContextMenu.cpp mode change 100644 => 100755 CPP/7zip/UI/Explorer/RegistryContextMenu.h mode change 100644 => 100755 CPP/7zip/UI/Explorer/StdAfx.cpp mode change 100644 => 100755 CPP/7zip/UI/Explorer/StdAfx.h mode change 100644 => 100755 CPP/7zip/UI/Explorer/makefile mode change 100644 => 100755 CPP/7zip/UI/Explorer/resource.h mode change 100644 => 100755 CPP/7zip/UI/Explorer/resource.rc mode change 100644 => 100755 CPP/7zip/UI/Explorer/resource2.rc mode change 100644 => 100755 CPP/7zip/UI/Far/ExtractEngine.cpp mode change 100644 => 100755 CPP/7zip/UI/Far/ExtractEngine.h mode change 100644 => 100755 CPP/7zip/UI/Far/Far.cpp mode change 100644 => 100755 CPP/7zip/UI/Far/Far.def mode change 100644 => 100755 CPP/7zip/UI/Far/Far.dsp mode change 100644 => 100755 CPP/7zip/UI/Far/Far.dsw mode change 100644 => 100755 CPP/7zip/UI/Far/FarPlugin.h mode change 100644 => 100755 CPP/7zip/UI/Far/FarUtils.cpp mode change 100644 => 100755 CPP/7zip/UI/Far/FarUtils.h mode change 100644 => 100755 CPP/7zip/UI/Far/Messages.h mode change 100644 => 100755 CPP/7zip/UI/Far/OverwriteDialogFar.cpp mode change 100644 => 100755 CPP/7zip/UI/Far/OverwriteDialogFar.h mode change 100644 => 100755 CPP/7zip/UI/Far/Plugin.cpp mode change 100644 => 100755 CPP/7zip/UI/Far/Plugin.h mode change 100644 => 100755 CPP/7zip/UI/Far/PluginCommon.cpp mode change 100644 => 100755 CPP/7zip/UI/Far/PluginDelete.cpp mode change 100644 => 100755 CPP/7zip/UI/Far/PluginRead.cpp mode change 100644 => 100755 CPP/7zip/UI/Far/PluginWrite.cpp mode change 100644 => 100755 CPP/7zip/UI/Far/ProgressBox.cpp mode change 100644 => 100755 CPP/7zip/UI/Far/ProgressBox.h mode change 100644 => 100755 CPP/7zip/UI/Far/StdAfx.cpp mode change 100644 => 100755 CPP/7zip/UI/Far/StdAfx.h mode change 100644 => 100755 CPP/7zip/UI/Far/UpdateCallbackFar.cpp mode change 100644 => 100755 CPP/7zip/UI/Far/UpdateCallbackFar.h mode change 100644 => 100755 CPP/7zip/UI/Far/makefile mode change 100644 => 100755 CPP/7zip/UI/Far/resource.rc mode change 100644 => 100755 CPP/7zip/UI/FileManager/7zFM.exe.manifest mode change 100644 => 100755 CPP/7zip/UI/FileManager/7zipLogo.ico mode change 100644 => 100755 CPP/7zip/UI/FileManager/AboutDialog.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/AboutDialog.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/AboutDialog.rc mode change 100644 => 100755 CPP/7zip/UI/FileManager/AboutDialogRes.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/Add.bmp mode change 100644 => 100755 CPP/7zip/UI/FileManager/Add2.bmp mode change 100644 => 100755 CPP/7zip/UI/FileManager/AltStreamsFolder.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/AltStreamsFolder.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/App.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/App.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/AppState.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/BrowseDialog.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/BrowseDialog.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/BrowseDialog.rc mode change 100644 => 100755 CPP/7zip/UI/FileManager/BrowseDialogRes.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/ClassDefs.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/ComboDialog.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/ComboDialog.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/ComboDialog.rc mode change 100644 => 100755 CPP/7zip/UI/FileManager/ComboDialogRes.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/Copy.bmp mode change 100644 => 100755 CPP/7zip/UI/FileManager/Copy2.bmp mode change 100644 => 100755 CPP/7zip/UI/FileManager/CopyDialog.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/CopyDialog.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/CopyDialog.rc mode change 100644 => 100755 CPP/7zip/UI/FileManager/CopyDialogRes.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/Delete.bmp mode change 100644 => 100755 CPP/7zip/UI/FileManager/Delete2.bmp mode change 100644 => 100755 CPP/7zip/UI/FileManager/DialogSize.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/EditDialog.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/EditDialog.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/EditDialog.rc mode change 100644 => 100755 CPP/7zip/UI/FileManager/EditDialogRes.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/EditPage.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/EditPage.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/EditPage.rc mode change 100644 => 100755 CPP/7zip/UI/FileManager/EditPage2.rc mode change 100644 => 100755 CPP/7zip/UI/FileManager/EditPageRes.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/EnumFormatEtc.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/EnumFormatEtc.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/Extract.bmp mode change 100644 => 100755 CPP/7zip/UI/FileManager/Extract2.bmp mode change 100644 => 100755 CPP/7zip/UI/FileManager/ExtractCallback.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/ExtractCallback.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/FM.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/FM.dsp mode change 100644 => 100755 CPP/7zip/UI/FileManager/FM.dsw mode change 100644 => 100755 CPP/7zip/UI/FileManager/FM.ico mode change 100644 => 100755 CPP/7zip/UI/FileManager/FM.mak mode change 100644 => 100755 CPP/7zip/UI/FileManager/FSDrives.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/FSDrives.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/FSFolder.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/FSFolder.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/FSFolderCopy.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/FileFolderPluginOpen.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/FilePlugins.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/FilePlugins.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/FoldersPage.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/FoldersPage.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/FoldersPage.rc mode change 100644 => 100755 CPP/7zip/UI/FileManager/FoldersPage2.rc mode change 100644 => 100755 CPP/7zip/UI/FileManager/FoldersPageRes.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/FormatUtils.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/FormatUtils.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/HelpUtils.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/HelpUtils.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/IFolder.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/Info.bmp mode change 100644 => 100755 CPP/7zip/UI/FileManager/Info2.bmp mode change 100644 => 100755 CPP/7zip/UI/FileManager/LangPage.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/LangPage.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/LangPage.rc mode change 100644 => 100755 CPP/7zip/UI/FileManager/LangPageRes.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/LangUtils.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/LangUtils.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/LinkDialog.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/LinkDialog.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/LinkDialog.rc mode change 100644 => 100755 CPP/7zip/UI/FileManager/LinkDialogRes.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/ListViewDialog.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/ListViewDialog.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/ListViewDialog.rc mode change 100644 => 100755 CPP/7zip/UI/FileManager/ListViewDialogRes.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/MenuPage.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/MenuPage.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/MenuPage.rc mode change 100644 => 100755 CPP/7zip/UI/FileManager/MenuPage2.rc mode change 100644 => 100755 CPP/7zip/UI/FileManager/MenuPageRes.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/MessagesDialog.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/MessagesDialog.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/MessagesDialog.rc mode change 100644 => 100755 CPP/7zip/UI/FileManager/MessagesDialogRes.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/Move.bmp mode change 100644 => 100755 CPP/7zip/UI/FileManager/Move2.bmp mode change 100644 => 100755 CPP/7zip/UI/FileManager/MyCom2.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/MyLoadMenu.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/MyLoadMenu.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/MyWindowsNew.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/NetFolder.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/NetFolder.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/OpenCallback.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/OpenCallback.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/OptionsDialog.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/OverwriteDialog.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/OverwriteDialog.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/OverwriteDialog.rc mode change 100644 => 100755 CPP/7zip/UI/FileManager/OverwriteDialogRes.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/Panel.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/Panel.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/PanelCopy.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/PanelCrc.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/PanelDrag.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/PanelFolderChange.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/PanelItemOpen.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/PanelItems.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/PanelKey.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/PanelListNotify.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/PanelMenu.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/PanelOperations.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/PanelSelect.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/PanelSort.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/PanelSplitFile.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/PasswordDialog.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/PasswordDialog.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/PasswordDialog.rc mode change 100644 => 100755 CPP/7zip/UI/FileManager/PasswordDialogRes.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/PluginInterface.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/PluginLoader.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/ProgramLocation.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/ProgramLocation.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/ProgressDialog.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/ProgressDialog.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/ProgressDialog.rc mode change 100644 => 100755 CPP/7zip/UI/FileManager/ProgressDialog2.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/ProgressDialog2.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/ProgressDialog2.rc mode change 100644 => 100755 CPP/7zip/UI/FileManager/ProgressDialog2Res.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/ProgressDialog2a.rc mode change 100644 => 100755 CPP/7zip/UI/FileManager/ProgressDialogRes.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/PropertyName.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/PropertyName.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/PropertyName.rc mode change 100644 => 100755 CPP/7zip/UI/FileManager/PropertyNameRes.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/RegistryAssociations.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/RegistryAssociations.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/RegistryPlugins.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/RegistryPlugins.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/RegistryUtils.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/RegistryUtils.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/RootFolder.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/RootFolder.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/SettingsPage.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/SettingsPage.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/SettingsPage.rc mode change 100644 => 100755 CPP/7zip/UI/FileManager/SettingsPage2.rc mode change 100644 => 100755 CPP/7zip/UI/FileManager/SettingsPageRes.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/SplitDialog.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/SplitDialog.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/SplitDialog.rc mode change 100644 => 100755 CPP/7zip/UI/FileManager/SplitDialogRes.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/SplitUtils.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/SplitUtils.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/StdAfx.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/StdAfx.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/StringUtils.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/StringUtils.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/SysIconUtils.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/SysIconUtils.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/SystemPage.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/SystemPage.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/SystemPage.rc mode change 100644 => 100755 CPP/7zip/UI/FileManager/SystemPageRes.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/Test.bmp mode change 100644 => 100755 CPP/7zip/UI/FileManager/Test2.bmp mode change 100644 => 100755 CPP/7zip/UI/FileManager/TextPairs.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/TextPairs.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/UpdateCallback100.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/UpdateCallback100.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/VerCtrl.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/ViewSettings.cpp mode change 100644 => 100755 CPP/7zip/UI/FileManager/ViewSettings.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/makefile mode change 100644 => 100755 CPP/7zip/UI/FileManager/resource.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/resource.rc mode change 100644 => 100755 CPP/7zip/UI/FileManager/resourceGui.h mode change 100644 => 100755 CPP/7zip/UI/FileManager/resourceGui.rc mode change 100644 => 100755 CPP/7zip/UI/GUI/7zG.exe.manifest mode change 100644 => 100755 CPP/7zip/UI/GUI/BenchmarkDialog.cpp mode change 100644 => 100755 CPP/7zip/UI/GUI/BenchmarkDialog.h mode change 100644 => 100755 CPP/7zip/UI/GUI/BenchmarkDialog.rc mode change 100644 => 100755 CPP/7zip/UI/GUI/BenchmarkDialogRes.h mode change 100644 => 100755 CPP/7zip/UI/GUI/CompressDialog.cpp mode change 100644 => 100755 CPP/7zip/UI/GUI/CompressDialog.h mode change 100644 => 100755 CPP/7zip/UI/GUI/CompressDialog.rc mode change 100644 => 100755 CPP/7zip/UI/GUI/CompressDialogRes.h create mode 100755 CPP/7zip/UI/GUI/CompressOptionsDialog.rc mode change 100644 => 100755 CPP/7zip/UI/GUI/Extract.rc mode change 100644 => 100755 CPP/7zip/UI/GUI/ExtractDialog.cpp mode change 100644 => 100755 CPP/7zip/UI/GUI/ExtractDialog.h mode change 100644 => 100755 CPP/7zip/UI/GUI/ExtractDialog.rc mode change 100644 => 100755 CPP/7zip/UI/GUI/ExtractDialogRes.h mode change 100644 => 100755 CPP/7zip/UI/GUI/ExtractGUI.cpp mode change 100644 => 100755 CPP/7zip/UI/GUI/ExtractGUI.h mode change 100644 => 100755 CPP/7zip/UI/GUI/ExtractRes.h mode change 100644 => 100755 CPP/7zip/UI/GUI/FM.ico mode change 100644 => 100755 CPP/7zip/UI/GUI/GUI.cpp mode change 100644 => 100755 CPP/7zip/UI/GUI/GUI.dsp mode change 100644 => 100755 CPP/7zip/UI/GUI/GUI.dsw mode change 100644 => 100755 CPP/7zip/UI/GUI/HashGUI.cpp mode change 100644 => 100755 CPP/7zip/UI/GUI/HashGUI.h mode change 100644 => 100755 CPP/7zip/UI/GUI/StdAfx.cpp mode change 100644 => 100755 CPP/7zip/UI/GUI/StdAfx.h mode change 100644 => 100755 CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp mode change 100644 => 100755 CPP/7zip/UI/GUI/UpdateCallbackGUI.h mode change 100644 => 100755 CPP/7zip/UI/GUI/UpdateCallbackGUI2.cpp mode change 100644 => 100755 CPP/7zip/UI/GUI/UpdateCallbackGUI2.h mode change 100644 => 100755 CPP/7zip/UI/GUI/UpdateGUI.cpp mode change 100644 => 100755 CPP/7zip/UI/GUI/UpdateGUI.h mode change 100644 => 100755 CPP/7zip/UI/GUI/makefile mode change 100644 => 100755 CPP/7zip/UI/GUI/resource.rc mode change 100644 => 100755 CPP/7zip/UI/GUI/resource2.h mode change 100644 => 100755 CPP/7zip/UI/GUI/resource2.rc mode change 100644 => 100755 CPP/7zip/UI/GUI/resource3.h mode change 100644 => 100755 CPP/7zip/UI/GUI/resource3.rc mode change 100644 => 100755 CPP/7zip/UI/makefile mode change 100644 => 100755 CPP/7zip/cmpl_clang.mak mode change 100644 => 100755 CPP/7zip/cmpl_clang_arm64.mak mode change 100644 => 100755 CPP/7zip/cmpl_clang_x64.mak mode change 100644 => 100755 CPP/7zip/cmpl_clang_x86.mak mode change 100644 => 100755 CPP/7zip/cmpl_gcc.mak mode change 100644 => 100755 CPP/7zip/cmpl_gcc_arm64.mak mode change 100644 => 100755 CPP/7zip/cmpl_gcc_x64.mak mode change 100644 => 100755 CPP/7zip/cmpl_gcc_x86.mak mode change 100644 => 100755 CPP/7zip/cmpl_mac_arm64.mak mode change 100644 => 100755 CPP/7zip/cmpl_mac_x64.mak mode change 100644 => 100755 CPP/7zip/makefile mode change 100644 => 100755 CPP/7zip/var_clang.mak mode change 100644 => 100755 CPP/7zip/var_clang_arm64.mak mode change 100644 => 100755 CPP/7zip/var_clang_x64.mak mode change 100644 => 100755 CPP/7zip/var_clang_x86.mak mode change 100644 => 100755 CPP/7zip/var_gcc.mak mode change 100644 => 100755 CPP/7zip/var_gcc_arm64.mak mode change 100644 => 100755 CPP/7zip/var_gcc_x64.mak mode change 100644 => 100755 CPP/7zip/var_gcc_x86.mak mode change 100644 => 100755 CPP/7zip/var_mac_arm64.mak mode change 100644 => 100755 CPP/7zip/var_mac_x64.mak mode change 100644 => 100755 CPP/7zip/warn_clang.mak mode change 100644 => 100755 CPP/7zip/warn_clang_mac.mak mode change 100644 => 100755 CPP/7zip/warn_gcc.mak mode change 100644 => 100755 CPP/Build.mak mode change 100644 => 100755 CPP/Common/AutoPtr.h mode change 100644 => 100755 CPP/Common/CRC.cpp mode change 100644 => 100755 CPP/Common/C_FileIO.cpp mode change 100644 => 100755 CPP/Common/C_FileIO.h mode change 100644 => 100755 CPP/Common/CksumReg.cpp mode change 100644 => 100755 CPP/Common/ComTry.h mode change 100644 => 100755 CPP/Common/CommandLineParser.cpp mode change 100644 => 100755 CPP/Common/CommandLineParser.h mode change 100644 => 100755 CPP/Common/Common.h mode change 100644 => 100755 CPP/Common/CrcReg.cpp mode change 100644 => 100755 CPP/Common/Defs.h mode change 100644 => 100755 CPP/Common/DynLimBuf.cpp mode change 100644 => 100755 CPP/Common/DynLimBuf.h mode change 100644 => 100755 CPP/Common/DynamicBuffer.h mode change 100644 => 100755 CPP/Common/IntToString.cpp mode change 100644 => 100755 CPP/Common/IntToString.h mode change 100644 => 100755 CPP/Common/Lang.cpp mode change 100644 => 100755 CPP/Common/Lang.h mode change 100644 => 100755 CPP/Common/ListFileUtils.cpp mode change 100644 => 100755 CPP/Common/ListFileUtils.h mode change 100644 => 100755 CPP/Common/LzFindPrepare.cpp mode change 100644 => 100755 CPP/Common/MyBuffer.h mode change 100644 => 100755 CPP/Common/MyBuffer2.h mode change 100644 => 100755 CPP/Common/MyCom.h mode change 100644 => 100755 CPP/Common/MyException.h mode change 100644 => 100755 CPP/Common/MyGuidDef.h mode change 100644 => 100755 CPP/Common/MyInitGuid.h mode change 100644 => 100755 CPP/Common/MyLinux.h mode change 100644 => 100755 CPP/Common/MyMap.cpp mode change 100644 => 100755 CPP/Common/MyMap.h mode change 100644 => 100755 CPP/Common/MyString.cpp mode change 100644 => 100755 CPP/Common/MyString.h mode change 100644 => 100755 CPP/Common/MyTypes.h mode change 100644 => 100755 CPP/Common/MyUnknown.h mode change 100644 => 100755 CPP/Common/MyVector.cpp mode change 100644 => 100755 CPP/Common/MyVector.h mode change 100644 => 100755 CPP/Common/MyWindows.cpp mode change 100644 => 100755 CPP/Common/MyWindows.h mode change 100644 => 100755 CPP/Common/MyXml.cpp mode change 100644 => 100755 CPP/Common/MyXml.h mode change 100644 => 100755 CPP/Common/NewHandler.cpp mode change 100644 => 100755 CPP/Common/NewHandler.h mode change 100644 => 100755 CPP/Common/Random.cpp mode change 100644 => 100755 CPP/Common/Random.h mode change 100644 => 100755 CPP/Common/Sha1Prepare.cpp mode change 100644 => 100755 CPP/Common/Sha1Reg.cpp mode change 100644 => 100755 CPP/Common/Sha256Prepare.cpp mode change 100644 => 100755 CPP/Common/Sha256Reg.cpp mode change 100644 => 100755 CPP/Common/StdAfx.h mode change 100644 => 100755 CPP/Common/StdInStream.cpp mode change 100644 => 100755 CPP/Common/StdInStream.h mode change 100644 => 100755 CPP/Common/StdOutStream.cpp mode change 100644 => 100755 CPP/Common/StdOutStream.h mode change 100644 => 100755 CPP/Common/StringConvert.cpp mode change 100644 => 100755 CPP/Common/StringConvert.h mode change 100644 => 100755 CPP/Common/StringToInt.cpp mode change 100644 => 100755 CPP/Common/StringToInt.h mode change 100644 => 100755 CPP/Common/TextConfig.cpp mode change 100644 => 100755 CPP/Common/TextConfig.h mode change 100644 => 100755 CPP/Common/UTFConvert.cpp mode change 100644 => 100755 CPP/Common/UTFConvert.h mode change 100644 => 100755 CPP/Common/Wildcard.cpp mode change 100644 => 100755 CPP/Common/Wildcard.h mode change 100644 => 100755 CPP/Common/XzCrc64Init.cpp mode change 100644 => 100755 CPP/Common/XzCrc64Reg.cpp mode change 100644 => 100755 CPP/Windows/COM.cpp mode change 100644 => 100755 CPP/Windows/COM.h mode change 100644 => 100755 CPP/Windows/Clipboard.cpp mode change 100644 => 100755 CPP/Windows/Clipboard.h mode change 100644 => 100755 CPP/Windows/CommonDialog.cpp mode change 100644 => 100755 CPP/Windows/CommonDialog.h mode change 100644 => 100755 CPP/Windows/Console.cpp mode change 100644 => 100755 CPP/Windows/Console.h mode change 100644 => 100755 CPP/Windows/Control/ComboBox.cpp mode change 100644 => 100755 CPP/Windows/Control/ComboBox.h mode change 100644 => 100755 CPP/Windows/Control/CommandBar.h mode change 100644 => 100755 CPP/Windows/Control/Dialog.cpp mode change 100644 => 100755 CPP/Windows/Control/Dialog.h mode change 100644 => 100755 CPP/Windows/Control/Edit.h mode change 100644 => 100755 CPP/Windows/Control/ImageList.cpp mode change 100644 => 100755 CPP/Windows/Control/ImageList.h mode change 100644 => 100755 CPP/Windows/Control/ListView.cpp mode change 100644 => 100755 CPP/Windows/Control/ListView.h mode change 100644 => 100755 CPP/Windows/Control/ProgressBar.h mode change 100644 => 100755 CPP/Windows/Control/PropertyPage.cpp mode change 100644 => 100755 CPP/Windows/Control/PropertyPage.h mode change 100644 => 100755 CPP/Windows/Control/ReBar.h mode change 100644 => 100755 CPP/Windows/Control/Static.h mode change 100644 => 100755 CPP/Windows/Control/StatusBar.h mode change 100644 => 100755 CPP/Windows/Control/StdAfx.h mode change 100644 => 100755 CPP/Windows/Control/ToolBar.h mode change 100644 => 100755 CPP/Windows/Control/Trackbar.h mode change 100644 => 100755 CPP/Windows/Control/Window2.cpp mode change 100644 => 100755 CPP/Windows/Control/Window2.h mode change 100644 => 100755 CPP/Windows/DLL.cpp mode change 100644 => 100755 CPP/Windows/DLL.h mode change 100644 => 100755 CPP/Windows/Defs.h mode change 100644 => 100755 CPP/Windows/ErrorMsg.cpp mode change 100644 => 100755 CPP/Windows/ErrorMsg.h mode change 100644 => 100755 CPP/Windows/FileDir.cpp mode change 100644 => 100755 CPP/Windows/FileDir.h mode change 100644 => 100755 CPP/Windows/FileFind.cpp mode change 100644 => 100755 CPP/Windows/FileFind.h mode change 100644 => 100755 CPP/Windows/FileIO.cpp mode change 100644 => 100755 CPP/Windows/FileIO.h mode change 100644 => 100755 CPP/Windows/FileLink.cpp mode change 100644 => 100755 CPP/Windows/FileMapping.cpp mode change 100644 => 100755 CPP/Windows/FileMapping.h mode change 100644 => 100755 CPP/Windows/FileName.cpp mode change 100644 => 100755 CPP/Windows/FileName.h mode change 100644 => 100755 CPP/Windows/FileSystem.cpp mode change 100644 => 100755 CPP/Windows/FileSystem.h mode change 100644 => 100755 CPP/Windows/Handle.h mode change 100644 => 100755 CPP/Windows/MemoryGlobal.cpp mode change 100644 => 100755 CPP/Windows/MemoryGlobal.h mode change 100644 => 100755 CPP/Windows/MemoryLock.cpp mode change 100644 => 100755 CPP/Windows/MemoryLock.h mode change 100644 => 100755 CPP/Windows/Menu.cpp mode change 100644 => 100755 CPP/Windows/Menu.h mode change 100644 => 100755 CPP/Windows/NationalTime.cpp mode change 100644 => 100755 CPP/Windows/NationalTime.h mode change 100644 => 100755 CPP/Windows/Net.cpp mode change 100644 => 100755 CPP/Windows/Net.h mode change 100644 => 100755 CPP/Windows/NtCheck.h mode change 100644 => 100755 CPP/Windows/ProcessMessages.cpp mode change 100644 => 100755 CPP/Windows/ProcessMessages.h mode change 100644 => 100755 CPP/Windows/ProcessUtils.cpp mode change 100644 => 100755 CPP/Windows/ProcessUtils.h mode change 100644 => 100755 CPP/Windows/PropVariant.cpp mode change 100644 => 100755 CPP/Windows/PropVariant.h mode change 100644 => 100755 CPP/Windows/PropVariantConv.cpp mode change 100644 => 100755 CPP/Windows/PropVariantConv.h mode change 100644 => 100755 CPP/Windows/PropVariantUtils.cpp mode change 100644 => 100755 CPP/Windows/PropVariantUtils.h mode change 100644 => 100755 CPP/Windows/Registry.cpp mode change 100644 => 100755 CPP/Windows/Registry.h mode change 100644 => 100755 CPP/Windows/ResourceString.cpp mode change 100644 => 100755 CPP/Windows/ResourceString.h mode change 100644 => 100755 CPP/Windows/SecurityUtils.cpp mode change 100644 => 100755 CPP/Windows/SecurityUtils.h mode change 100644 => 100755 CPP/Windows/Shell.cpp mode change 100644 => 100755 CPP/Windows/Shell.h mode change 100644 => 100755 CPP/Windows/StdAfx.h mode change 100644 => 100755 CPP/Windows/Synchronization.cpp mode change 100644 => 100755 CPP/Windows/Synchronization.h mode change 100644 => 100755 CPP/Windows/System.cpp mode change 100644 => 100755 CPP/Windows/System.h mode change 100644 => 100755 CPP/Windows/SystemInfo.cpp mode change 100644 => 100755 CPP/Windows/SystemInfo.h mode change 100644 => 100755 CPP/Windows/Thread.h mode change 100644 => 100755 CPP/Windows/TimeUtils.cpp mode change 100644 => 100755 CPP/Windows/TimeUtils.h mode change 100644 => 100755 CPP/Windows/Window.cpp mode change 100644 => 100755 CPP/Windows/Window.h mode change 100644 => 100755 DOC/7zC.txt mode change 100644 => 100755 DOC/7zFormat.txt mode change 100644 => 100755 DOC/7zip.hhp mode change 100644 => 100755 DOC/7zip.wxs mode change 100644 => 100755 DOC/License.txt mode change 100644 => 100755 DOC/Methods.txt mode change 100644 => 100755 DOC/copying.txt mode change 100644 => 100755 DOC/lzma.txt mode change 100644 => 100755 DOC/readme.txt mode change 100644 => 100755 DOC/src-history.txt mode change 100644 => 100755 DOC/unRarLicense.txt diff --git a/Asm/arm/7zCrcOpt.asm b/Asm/arm/7zCrcOpt.asm old mode 100644 new mode 100755 diff --git a/Asm/arm64/7zAsm.S b/Asm/arm64/7zAsm.S old mode 100644 new mode 100755 diff --git a/Asm/arm64/LzmaDecOpt.S b/Asm/arm64/LzmaDecOpt.S old mode 100644 new mode 100755 diff --git a/Asm/x86/7zAsm.asm b/Asm/x86/7zAsm.asm old mode 100644 new mode 100755 index 6275bb745..19c40dac4 --- 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 old mode 100644 new mode 100755 diff --git a/Asm/x86/AesOpt.asm b/Asm/x86/AesOpt.asm old mode 100644 new mode 100755 diff --git a/Asm/x86/LzFindOpt.asm b/Asm/x86/LzFindOpt.asm old mode 100644 new mode 100755 diff --git a/Asm/x86/LzmaDecOpt.asm b/Asm/x86/LzmaDecOpt.asm old mode 100644 new mode 100755 diff --git a/Asm/x86/Sha1Opt.asm b/Asm/x86/Sha1Opt.asm old mode 100644 new mode 100755 diff --git a/Asm/x86/Sha256Opt.asm b/Asm/x86/Sha256Opt.asm old mode 100644 new mode 100755 index 5d02c90ae..3e9f6eda3 --- 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 old mode 100644 new mode 100755 diff --git a/C/7z.h b/C/7z.h old mode 100644 new mode 100755 diff --git a/C/7zAlloc.c b/C/7zAlloc.c old mode 100644 new mode 100755 diff --git a/C/7zAlloc.h b/C/7zAlloc.h old mode 100644 new mode 100755 diff --git a/C/7zArcIn.c b/C/7zArcIn.c old mode 100644 new mode 100755 diff --git a/C/7zBuf.c b/C/7zBuf.c old mode 100644 new mode 100755 diff --git a/C/7zBuf.h b/C/7zBuf.h old mode 100644 new mode 100755 diff --git a/C/7zBuf2.c b/C/7zBuf2.c old mode 100644 new mode 100755 diff --git a/C/7zCrc.c b/C/7zCrc.c old mode 100644 new mode 100755 diff --git a/C/7zCrc.h b/C/7zCrc.h old mode 100644 new mode 100755 diff --git a/C/7zCrcOpt.c b/C/7zCrcOpt.c old mode 100644 new mode 100755 diff --git a/C/7zDec.c b/C/7zDec.c old mode 100644 new mode 100755 diff --git a/C/7zFile.c b/C/7zFile.c old mode 100644 new mode 100755 diff --git a/C/7zFile.h b/C/7zFile.h old mode 100644 new mode 100755 diff --git a/C/7zStream.c b/C/7zStream.c old mode 100644 new mode 100755 diff --git a/C/7zTypes.h b/C/7zTypes.h old mode 100644 new mode 100755 index fe4fde3ff..f7d707183 --- 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 old mode 100644 new mode 100755 index e9363d37b..89fffd967 --- 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 old mode 100644 new mode 100755 diff --git a/C/7zip_gcc_c.mak b/C/7zip_gcc_c.mak old mode 100644 new mode 100755 diff --git a/C/Aes.c b/C/Aes.c old mode 100644 new mode 100755 diff --git a/C/Aes.h b/C/Aes.h old mode 100644 new mode 100755 diff --git a/C/AesOpt.c b/C/AesOpt.c old mode 100644 new mode 100755 diff --git a/C/Alloc.c b/C/Alloc.c old mode 100644 new mode 100755 diff --git a/C/Alloc.h b/C/Alloc.h old mode 100644 new mode 100755 diff --git a/C/Bcj2.c b/C/Bcj2.c old mode 100644 new mode 100755 diff --git a/C/Bcj2.h b/C/Bcj2.h old mode 100644 new mode 100755 diff --git a/C/Bcj2Enc.c b/C/Bcj2Enc.c old mode 100644 new mode 100755 diff --git a/C/Blake2.h b/C/Blake2.h old mode 100644 new mode 100755 diff --git a/C/Blake2s.c b/C/Blake2s.c old mode 100644 new mode 100755 diff --git a/C/Bra.c b/C/Bra.c old mode 100644 new mode 100755 diff --git a/C/Bra.h b/C/Bra.h old mode 100644 new mode 100755 diff --git a/C/Bra86.c b/C/Bra86.c old mode 100644 new mode 100755 diff --git a/C/BraIA64.c b/C/BraIA64.c old mode 100644 new mode 100755 diff --git a/C/BwtSort.c b/C/BwtSort.c old mode 100644 new mode 100755 diff --git a/C/BwtSort.h b/C/BwtSort.h old mode 100644 new mode 100755 diff --git a/C/Compiler.h b/C/Compiler.h old mode 100644 new mode 100755 diff --git a/C/CpuArch.c b/C/CpuArch.c old mode 100644 new mode 100755 diff --git a/C/CpuArch.h b/C/CpuArch.h old mode 100644 new mode 100755 diff --git a/C/Delta.c b/C/Delta.c old mode 100644 new mode 100755 diff --git a/C/Delta.h b/C/Delta.h old mode 100644 new mode 100755 diff --git a/C/DllSecur.c b/C/DllSecur.c old mode 100644 new mode 100755 diff --git a/C/DllSecur.h b/C/DllSecur.h old mode 100644 new mode 100755 diff --git a/C/HuffEnc.c b/C/HuffEnc.c old mode 100644 new mode 100755 diff --git a/C/HuffEnc.h b/C/HuffEnc.h old mode 100644 new mode 100755 diff --git a/C/LzFind.c b/C/LzFind.c old mode 100644 new mode 100755 diff --git a/C/LzFind.h b/C/LzFind.h old mode 100644 new mode 100755 diff --git a/C/LzFindMt.c b/C/LzFindMt.c old mode 100644 new mode 100755 diff --git a/C/LzFindMt.h b/C/LzFindMt.h old mode 100644 new mode 100755 diff --git a/C/LzFindOpt.c b/C/LzFindOpt.c old mode 100644 new mode 100755 diff --git a/C/LzHash.h b/C/LzHash.h old mode 100644 new mode 100755 diff --git a/C/Lzma2Dec.c b/C/Lzma2Dec.c old mode 100644 new mode 100755 diff --git a/C/Lzma2Dec.h b/C/Lzma2Dec.h old mode 100644 new mode 100755 diff --git a/C/Lzma2DecMt.c b/C/Lzma2DecMt.c old mode 100644 new mode 100755 diff --git a/C/Lzma2DecMt.h b/C/Lzma2DecMt.h old mode 100644 new mode 100755 diff --git a/C/Lzma2Enc.c b/C/Lzma2Enc.c old mode 100644 new mode 100755 diff --git a/C/Lzma2Enc.h b/C/Lzma2Enc.h old mode 100644 new mode 100755 diff --git a/C/Lzma86.h b/C/Lzma86.h old mode 100644 new mode 100755 diff --git a/C/Lzma86Dec.c b/C/Lzma86Dec.c old mode 100644 new mode 100755 diff --git a/C/Lzma86Enc.c b/C/Lzma86Enc.c old mode 100644 new mode 100755 diff --git a/C/LzmaDec.c b/C/LzmaDec.c old mode 100644 new mode 100755 diff --git a/C/LzmaDec.h b/C/LzmaDec.h old mode 100644 new mode 100755 diff --git a/C/LzmaEnc.c b/C/LzmaEnc.c old mode 100644 new mode 100755 diff --git a/C/LzmaEnc.h b/C/LzmaEnc.h old mode 100644 new mode 100755 diff --git a/C/LzmaLib.c b/C/LzmaLib.c old mode 100644 new mode 100755 diff --git a/C/LzmaLib.h b/C/LzmaLib.h old mode 100644 new mode 100755 diff --git a/C/MtCoder.c b/C/MtCoder.c old mode 100644 new mode 100755 diff --git a/C/MtCoder.h b/C/MtCoder.h old mode 100644 new mode 100755 diff --git a/C/MtDec.c b/C/MtDec.c old mode 100644 new mode 100755 diff --git a/C/MtDec.h b/C/MtDec.h old mode 100644 new mode 100755 diff --git a/C/Ppmd.h b/C/Ppmd.h old mode 100644 new mode 100755 diff --git a/C/Ppmd7.c b/C/Ppmd7.c old mode 100644 new mode 100755 diff --git a/C/Ppmd7.h b/C/Ppmd7.h old mode 100644 new mode 100755 diff --git a/C/Ppmd7Dec.c b/C/Ppmd7Dec.c old mode 100644 new mode 100755 diff --git a/C/Ppmd7Enc.c b/C/Ppmd7Enc.c old mode 100644 new mode 100755 diff --git a/C/Ppmd7aDec.c b/C/Ppmd7aDec.c old mode 100644 new mode 100755 diff --git a/C/Ppmd8.c b/C/Ppmd8.c old mode 100644 new mode 100755 diff --git a/C/Ppmd8.h b/C/Ppmd8.h old mode 100644 new mode 100755 diff --git a/C/Ppmd8Dec.c b/C/Ppmd8Dec.c old mode 100644 new mode 100755 diff --git a/C/Ppmd8Enc.c b/C/Ppmd8Enc.c old mode 100644 new mode 100755 diff --git a/C/Precomp.h b/C/Precomp.h old mode 100644 new mode 100755 diff --git a/C/RotateDefs.h b/C/RotateDefs.h old mode 100644 new mode 100755 diff --git a/C/Sha1.c b/C/Sha1.c old mode 100644 new mode 100755 diff --git a/C/Sha1.h b/C/Sha1.h old mode 100644 new mode 100755 diff --git a/C/Sha1Opt.c b/C/Sha1Opt.c old mode 100644 new mode 100755 diff --git a/C/Sha256.c b/C/Sha256.c old mode 100644 new mode 100755 diff --git a/C/Sha256.h b/C/Sha256.h old mode 100644 new mode 100755 diff --git a/C/Sha256Opt.c b/C/Sha256Opt.c old mode 100644 new mode 100755 diff --git a/C/Sort.c b/C/Sort.c old mode 100644 new mode 100755 diff --git a/C/Sort.h b/C/Sort.h old mode 100644 new mode 100755 diff --git a/C/Threads.c b/C/Threads.c old mode 100644 new mode 100755 diff --git a/C/Threads.h b/C/Threads.h old mode 100644 new mode 100755 diff --git a/C/Util/7z/7z.dsp b/C/Util/7z/7z.dsp old mode 100644 new mode 100755 diff --git a/C/Util/7z/7z.dsw b/C/Util/7z/7z.dsw old mode 100644 new mode 100755 diff --git a/C/Util/7z/7zMain.c b/C/Util/7z/7zMain.c old mode 100644 new mode 100755 diff --git a/C/Util/7z/Precomp.c b/C/Util/7z/Precomp.c old mode 100644 new mode 100755 diff --git a/C/Util/7z/Precomp.h b/C/Util/7z/Precomp.h old mode 100644 new mode 100755 diff --git a/C/Util/7z/makefile b/C/Util/7z/makefile old mode 100644 new mode 100755 diff --git a/C/Util/7z/makefile.gcc b/C/Util/7z/makefile.gcc old mode 100644 new mode 100755 diff --git a/C/Util/7zipInstall/7zip.ico b/C/Util/7zipInstall/7zip.ico old mode 100644 new mode 100755 diff --git a/C/Util/7zipInstall/7zipInstall.c b/C/Util/7zipInstall/7zipInstall.c old mode 100644 new mode 100755 diff --git a/C/Util/7zipInstall/7zipInstall.dsp b/C/Util/7zipInstall/7zipInstall.dsp old mode 100644 new mode 100755 diff --git a/C/Util/7zipInstall/7zipInstall.dsw b/C/Util/7zipInstall/7zipInstall.dsw old mode 100644 new mode 100755 diff --git a/C/Util/7zipInstall/7zipInstall.manifest b/C/Util/7zipInstall/7zipInstall.manifest old mode 100644 new mode 100755 diff --git a/C/Util/7zipInstall/Precomp.c b/C/Util/7zipInstall/Precomp.c old mode 100644 new mode 100755 diff --git a/C/Util/7zipInstall/Precomp.h b/C/Util/7zipInstall/Precomp.h old mode 100644 new mode 100755 diff --git a/C/Util/7zipInstall/makefile b/C/Util/7zipInstall/makefile old mode 100644 new mode 100755 diff --git a/C/Util/7zipInstall/resource.h b/C/Util/7zipInstall/resource.h old mode 100644 new mode 100755 diff --git a/C/Util/7zipInstall/resource.rc b/C/Util/7zipInstall/resource.rc old mode 100644 new mode 100755 diff --git a/C/Util/7zipUninstall/7zipUninstall.c b/C/Util/7zipUninstall/7zipUninstall.c old mode 100644 new mode 100755 diff --git a/C/Util/7zipUninstall/7zipUninstall.dsp b/C/Util/7zipUninstall/7zipUninstall.dsp old mode 100644 new mode 100755 diff --git a/C/Util/7zipUninstall/7zipUninstall.dsw b/C/Util/7zipUninstall/7zipUninstall.dsw old mode 100644 new mode 100755 diff --git a/C/Util/7zipUninstall/7zipUninstall.ico b/C/Util/7zipUninstall/7zipUninstall.ico old mode 100644 new mode 100755 diff --git a/C/Util/7zipUninstall/7zipUninstall.manifest b/C/Util/7zipUninstall/7zipUninstall.manifest old mode 100644 new mode 100755 diff --git a/C/Util/7zipUninstall/Precomp.c b/C/Util/7zipUninstall/Precomp.c old mode 100644 new mode 100755 diff --git a/C/Util/7zipUninstall/Precomp.h b/C/Util/7zipUninstall/Precomp.h old mode 100644 new mode 100755 diff --git a/C/Util/7zipUninstall/makefile b/C/Util/7zipUninstall/makefile old mode 100644 new mode 100755 diff --git a/C/Util/7zipUninstall/resource.h b/C/Util/7zipUninstall/resource.h old mode 100644 new mode 100755 diff --git a/C/Util/7zipUninstall/resource.rc b/C/Util/7zipUninstall/resource.rc old mode 100644 new mode 100755 diff --git a/C/Util/Lzma/LzmaUtil.c b/C/Util/Lzma/LzmaUtil.c old mode 100644 new mode 100755 diff --git a/C/Util/Lzma/LzmaUtil.dsp b/C/Util/Lzma/LzmaUtil.dsp old mode 100644 new mode 100755 diff --git a/C/Util/Lzma/LzmaUtil.dsw b/C/Util/Lzma/LzmaUtil.dsw old mode 100644 new mode 100755 diff --git a/C/Util/Lzma/makefile b/C/Util/Lzma/makefile old mode 100644 new mode 100755 diff --git a/C/Util/Lzma/makefile.gcc b/C/Util/Lzma/makefile.gcc old mode 100644 new mode 100755 diff --git a/C/Util/LzmaLib/LzmaLib.def b/C/Util/LzmaLib/LzmaLib.def old mode 100644 new mode 100755 diff --git a/C/Util/LzmaLib/LzmaLib.dsp b/C/Util/LzmaLib/LzmaLib.dsp old mode 100644 new mode 100755 diff --git a/C/Util/LzmaLib/LzmaLib.dsw b/C/Util/LzmaLib/LzmaLib.dsw old mode 100644 new mode 100755 diff --git a/C/Util/LzmaLib/LzmaLibExports.c b/C/Util/LzmaLib/LzmaLibExports.c old mode 100644 new mode 100755 diff --git a/C/Util/LzmaLib/makefile b/C/Util/LzmaLib/makefile old mode 100644 new mode 100755 diff --git a/C/Util/LzmaLib/resource.rc b/C/Util/LzmaLib/resource.rc old mode 100644 new mode 100755 diff --git a/C/Util/SfxSetup/Precomp.c b/C/Util/SfxSetup/Precomp.c old mode 100644 new mode 100755 diff --git a/C/Util/SfxSetup/Precomp.h b/C/Util/SfxSetup/Precomp.h old mode 100644 new mode 100755 diff --git a/C/Util/SfxSetup/SfxSetup.c b/C/Util/SfxSetup/SfxSetup.c old mode 100644 new mode 100755 diff --git a/C/Util/SfxSetup/SfxSetup.dsp b/C/Util/SfxSetup/SfxSetup.dsp old mode 100644 new mode 100755 diff --git a/C/Util/SfxSetup/SfxSetup.dsw b/C/Util/SfxSetup/SfxSetup.dsw old mode 100644 new mode 100755 diff --git a/C/Util/SfxSetup/makefile b/C/Util/SfxSetup/makefile old mode 100644 new mode 100755 diff --git a/C/Util/SfxSetup/makefile_con b/C/Util/SfxSetup/makefile_con old mode 100644 new mode 100755 diff --git a/C/Util/SfxSetup/resource.rc b/C/Util/SfxSetup/resource.rc old mode 100644 new mode 100755 diff --git a/C/Util/SfxSetup/setup.ico b/C/Util/SfxSetup/setup.ico old mode 100644 new mode 100755 diff --git a/C/Xz.c b/C/Xz.c old mode 100644 new mode 100755 diff --git a/C/Xz.h b/C/Xz.h old mode 100644 new mode 100755 diff --git a/C/XzCrc64.c b/C/XzCrc64.c old mode 100644 new mode 100755 diff --git a/C/XzCrc64.h b/C/XzCrc64.h old mode 100644 new mode 100755 diff --git a/C/XzCrc64Opt.c b/C/XzCrc64Opt.c old mode 100644 new mode 100755 diff --git a/C/XzDec.c b/C/XzDec.c old mode 100644 new mode 100755 diff --git a/C/XzEnc.c b/C/XzEnc.c old mode 100644 new mode 100755 diff --git a/C/XzEnc.h b/C/XzEnc.h old mode 100644 new mode 100755 diff --git a/C/XzIn.c b/C/XzIn.c old mode 100644 new mode 100755 diff --git a/C/var_clang.mak b/C/var_clang.mak old mode 100644 new mode 100755 diff --git a/C/var_clang_arm64.mak b/C/var_clang_arm64.mak old mode 100644 new mode 100755 diff --git a/C/var_clang_x64.mak b/C/var_clang_x64.mak old mode 100644 new mode 100755 diff --git a/C/var_clang_x86.mak b/C/var_clang_x86.mak old mode 100644 new mode 100755 diff --git a/C/var_gcc.mak b/C/var_gcc.mak old mode 100644 new mode 100755 diff --git a/C/var_gcc_arm64.mak b/C/var_gcc_arm64.mak old mode 100644 new mode 100755 diff --git a/C/var_gcc_x64.mak b/C/var_gcc_x64.mak old mode 100644 new mode 100755 diff --git a/C/var_gcc_x86.mak b/C/var_gcc_x86.mak old mode 100644 new mode 100755 diff --git a/C/var_mac_arm64.mak b/C/var_mac_arm64.mak old mode 100644 new mode 100755 diff --git a/C/var_mac_x64.mak b/C/var_mac_x64.mak old mode 100644 new mode 100755 diff --git a/C/warn_clang.mak b/C/warn_clang.mak old mode 100644 new mode 100755 diff --git a/C/warn_clang_mac.mak b/C/warn_clang_mac.mak old mode 100644 new mode 100755 diff --git a/C/warn_gcc.mak b/C/warn_gcc.mak old mode 100644 new mode 100755 diff --git a/CPP/7zip/7zip.mak b/CPP/7zip/7zip.mak old mode 100644 new mode 100755 diff --git a/CPP/7zip/7zip_gcc.mak b/CPP/7zip/7zip_gcc.mak old mode 100644 new mode 100755 index e2698a6e8..b24245941 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/7z/7z.dsp b/CPP/7zip/Archive/7z/7z.dsp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/7z/7z.dsw b/CPP/7zip/Archive/7z/7z.dsw old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/7z/7zCompressionMode.cpp b/CPP/7zip/Archive/7z/7zCompressionMode.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/7z/7zCompressionMode.h b/CPP/7zip/Archive/7z/7zCompressionMode.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/7z/7zDecode.cpp b/CPP/7zip/Archive/7z/7zDecode.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/7z/7zDecode.h b/CPP/7zip/Archive/7z/7zDecode.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/7z/7zEncode.cpp b/CPP/7zip/Archive/7z/7zEncode.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/7z/7zEncode.h b/CPP/7zip/Archive/7z/7zEncode.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/7z/7zExtract.cpp b/CPP/7zip/Archive/7z/7zExtract.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/7z/7zFolderInStream.cpp b/CPP/7zip/Archive/7z/7zFolderInStream.cpp old mode 100644 new mode 100755 index a68edf4eb..cf50e6948 --- 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 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 streamGetSize; - stream.QueryInterface(IID_IStreamGetSize, &streamGetSize); - if (streamGetSize) { - if (streamGetSize->GetSize(&_size) == S_OK) - _size_Defined = true; + CMyComPtr 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 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 &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 old mode 100644 new mode 100755 index 805db54e9..f054e6818 --- 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 _updateCallback; HRESULT OpenStream(); - void AddFileInfo(bool isProcessed); + HRESULT AddFileInfo(bool isProcessed); public: CRecordVector Processed; CRecordVector CRCs; CRecordVector Sizes; + CRecordVector CTimes; + CRecordVector ATimes; + CRecordVector MTimes; + CRecordVector Attribs; + CRecordVector TimesDefined; + + bool Need_CTime; + bool Need_ATime; + bool Need_MTime; + bool Need_Attrib; + + // CMyComPtr _reportArcProp; MY_UNKNOWN_IMP2(ISequentialInStream, ICompressGetSubStreamSize) STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); @@ -45,7 +61,7 @@ class CFolderInStream: 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 @@ class CFolderInStream: 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 old mode 100644 new mode 100755 index 9e344c349..ca22f8814 --- 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 old mode 100644 new mode 100755 index cbc2d028a..08bd65407 --- a/CPP/7zip/Archive/7z/7zHandler.h +++ b/CPP/7zip/Archive/7z/7zHandler.h @@ -49,9 +49,8 @@ class COutHandler: public CMultiMethodProps 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 old mode 100644 new mode 100755 index 8f875ce48..bf4e7a69c --- 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 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/7z/7zHeader.h b/CPP/7zip/Archive/7z/7zHeader.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/7z/7zIn.cpp b/CPP/7zip/Archive/7z/7zIn.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/7z/7zIn.h b/CPP/7zip/Archive/7z/7zIn.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/7z/7zItem.h b/CPP/7zip/Archive/7z/7zItem.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/7z/7zOut.cpp b/CPP/7zip/Archive/7z/7zOut.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/7z/7zOut.h b/CPP/7zip/Archive/7z/7zOut.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/7z/7zProperties.cpp b/CPP/7zip/Archive/7z/7zProperties.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/7z/7zProperties.h b/CPP/7zip/Archive/7z/7zProperties.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/7z/7zRegister.cpp b/CPP/7zip/Archive/7z/7zRegister.cpp old mode 100644 new mode 100755 index 389b54074..eac8b4f2d --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/7z/7zSpecStream.h b/CPP/7zip/Archive/7z/7zSpecStream.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/7z/7zUpdate.cpp b/CPP/7zip/Archive/7z/7zUpdate.cpp old mode 100644 new mode 100755 index b641d93f9..b6fd1924e --- 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 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 extractCallback; updateCallback->QueryInterface(IID_IArchiveExtractCallbackMessage, (void **)&extractCallback); + /* + CMyComPtr 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 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 old mode 100644 new mode 100755 index 7c0f78a8a..e6c48caee --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/7z/StdAfx.h b/CPP/7zip/Archive/7z/StdAfx.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/7z/makefile b/CPP/7zip/Archive/7z/makefile old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/7z/resource.rc b/CPP/7zip/Archive/7z/resource.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/ApfsHandler.cpp b/CPP/7zip/Archive/ApfsHandler.cpp new file mode 100755 index 000000000..8312456bf --- /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 +#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 Extents; + CObjectVector 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 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 Nodes; + CRecordVector NodeIDs; + CObjectVector Items; + CRecordVector Refs; + + CObjectVector SmallNodes; + CRecordVector 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 Keys; + CRecordVector Vals; + + bool Parse(const CObjectVector &pairs); + int FindKey(UInt64 id) const { return Keys.FindInSorted(id); } +}; + +bool CObjectMap::Parse(const CObjectVector &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 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 Refs2; + CObjectVector Vols; + + bool HeadersError; + bool ThereAreAltStreams; + bool UnsupportedFeature; + + CSuperBlock sb; + + IInStream *OpenInStream; + IArchiveOpenCallback *OpenCallback; + UInt64 ProgressVal_Cur; + UInt64 ProgressVal_Prev; + UInt64 ProgressVal_NumFilesTotal; + CObjectVector 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 *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 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 _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 progress = lps; + lps->Init(extractCallback, false); + + NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); + CMyComPtr 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 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 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 *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 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 *extents, UInt64 rem, + ISequentialInStream **stream) +{ + CExtentsStream *extentStreamSpec = new CExtentsStream(); + CMyComPtr 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/ArHandler.cpp b/CPP/7zip/Archive/ArHandler.cpp old mode 100644 new mode 100755 index 0bea8b4eb..6cd72bb3f --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Archive2.def b/CPP/7zip/Archive/Archive2.def old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/ArchiveExports.cpp b/CPP/7zip/Archive/ArchiveExports.cpp old mode 100644 new mode 100755 index 6549b3d23..8a441bc28 --- 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 old mode 100644 new mode 100755 index 0e353dcab..125b9c20c --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Bz2Handler.cpp b/CPP/7zip/Archive/Bz2Handler.cpp old mode 100644 new mode 100755 index b0c2f7508..c89a53c5b --- 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 fileInStream; - RINOK(updateCallback->GetStream(0, &fileInStream)); - CLocalProgress *localProgressSpec = new CLocalProgress; - CMyComPtr localProgress = localProgressSpec; - localProgressSpec->Init(updateCallback, true); - NCompress::NBZip2::CEncoder *encoderSpec = new NCompress::NBZip2::CEncoder; - CMyComPtr encoder = encoderSpec; - RINOK(props.SetCoderProps(encoderSpec, NULL)); - RINOK(encoder->Code(fileInStream, outStream, NULL, NULL, localProgress)); + { + CMyComPtr fileInStream; + RINOK(updateCallback->GetStream(0, &fileInStream)); + if (!fileInStream) + return S_FALSE; + { + CMyComPtr 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 localProgress = localProgressSpec; + localProgressSpec->Init(updateCallback, true); + { + NCompress::NBZip2::CEncoder *encoderSpec = new NCompress::NBZip2::CEncoder; + CMyComPtr 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 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Cab/CabBlockInStream.h b/CPP/7zip/Archive/Cab/CabBlockInStream.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Cab/CabHandler.cpp b/CPP/7zip/Archive/Cab/CabHandler.cpp old mode 100644 new mode 100755 index fafd7aa03..804c921a0 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Cab/CabHeader.cpp b/CPP/7zip/Archive/Cab/CabHeader.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Cab/CabHeader.h b/CPP/7zip/Archive/Cab/CabHeader.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Cab/CabIn.cpp b/CPP/7zip/Archive/Cab/CabIn.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Cab/CabIn.h b/CPP/7zip/Archive/Cab/CabIn.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Cab/CabItem.h b/CPP/7zip/Archive/Cab/CabItem.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Cab/CabRegister.cpp b/CPP/7zip/Archive/Cab/CabRegister.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Cab/StdAfx.h b/CPP/7zip/Archive/Cab/StdAfx.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Chm/ChmHandler.cpp b/CPP/7zip/Archive/Chm/ChmHandler.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Chm/ChmHandler.h b/CPP/7zip/Archive/Chm/ChmHandler.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Chm/ChmIn.cpp b/CPP/7zip/Archive/Chm/ChmIn.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Chm/ChmIn.h b/CPP/7zip/Archive/Chm/ChmIn.h old mode 100644 new mode 100755 index f7b75d811..7cba0c716 --- a/CPP/7zip/Archive/Chm/ChmIn.h +++ b/CPP/7zip/Archive/Chm/ChmIn.h @@ -84,6 +84,11 @@ struct CResetTable // unsigned BlockSizeBits; CRecordVector 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/ComHandler.cpp b/CPP/7zip/Archive/ComHandler.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Common/CoderMixer2.cpp b/CPP/7zip/Archive/Common/CoderMixer2.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Common/CoderMixer2.h b/CPP/7zip/Archive/Common/CoderMixer2.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Common/DummyOutStream.cpp b/CPP/7zip/Archive/Common/DummyOutStream.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Common/DummyOutStream.h b/CPP/7zip/Archive/Common/DummyOutStream.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Common/FindSignature.cpp b/CPP/7zip/Archive/Common/FindSignature.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Common/FindSignature.h b/CPP/7zip/Archive/Common/FindSignature.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Common/HandlerOut.cpp b/CPP/7zip/Archive/Common/HandlerOut.cpp old mode 100644 new mode 100755 index 89012204f..1b9a93ebf --- 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 old mode 100644 new mode 100755 index b3d07e9e9..41ee189d1 --- 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 @@ class CSingleMethodProps: public COneMethodInfo, public CCommonMethodProps 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Common/InStreamWithCRC.h b/CPP/7zip/Archive/Common/InStreamWithCRC.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Common/ItemNameUtils.cpp b/CPP/7zip/Archive/Common/ItemNameUtils.cpp old mode 100644 new mode 100755 index 905a863d2..8caf1d141 --- 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 old mode 100644 new mode 100755 index 6a4d6c718..3f5f4e8a4 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Common/MultiStream.h b/CPP/7zip/Archive/Common/MultiStream.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp b/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Common/OutStreamWithCRC.h b/CPP/7zip/Archive/Common/OutStreamWithCRC.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Common/OutStreamWithSha1.cpp b/CPP/7zip/Archive/Common/OutStreamWithSha1.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Common/OutStreamWithSha1.h b/CPP/7zip/Archive/Common/OutStreamWithSha1.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Common/ParseProperties.cpp b/CPP/7zip/Archive/Common/ParseProperties.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Common/ParseProperties.h b/CPP/7zip/Archive/Common/ParseProperties.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Common/StdAfx.h b/CPP/7zip/Archive/Common/StdAfx.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/CpioHandler.cpp b/CPP/7zip/Archive/CpioHandler.cpp old mode 100644 new mode 100755 index ffdab16cd..b7e7564f9 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/DeflateProps.cpp b/CPP/7zip/Archive/DeflateProps.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/DeflateProps.h b/CPP/7zip/Archive/DeflateProps.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/DllExports.cpp b/CPP/7zip/Archive/DllExports.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/DllExports2.cpp b/CPP/7zip/Archive/DllExports2.cpp old mode 100644 new mode 100755 index 967a7cbfd..1f7148615 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/ElfHandler.cpp b/CPP/7zip/Archive/ElfHandler.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/ExtHandler.cpp b/CPP/7zip/Archive/ExtHandler.cpp old mode 100644 new mode 100755 index 6c095d9a6..01e12edc6 --- 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 old mode 100644 new mode 100755 index 1cbc8508f..826b4fd13 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/GptHandler.cpp b/CPP/7zip/Archive/GptHandler.cpp old mode 100644 new mode 100755 index 2b3a673b1..0d2caa3df --- 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 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 old mode 100644 new mode 100755 index 0054840dd..35e642eca --- 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 @@ class CHandler: 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 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 fileInStream; RINOK(updateCallback->GetStream(0, &fileInStream)); + if (!fileInStream) + return S_FALSE; + + { + CMyComPtr 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 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 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 old mode 100644 new mode 100755 index 6f196de82..3cbfdacd0 --- 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 _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 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 progress = lps; + lps->Init(extractCallback, false); + + if (Init_PackSizeProcessed()) + { + CHandlerImgProgress *imgProgressSpec = new CHandlerImgProgress(*this); + CMyComPtr imgProgress = imgProgressSpec; + imgProgressSpec->_ratioProgress = progress; + progress.Release(); + progress = imgProgress; + } + NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); CMyComPtr copyCoder = copyCoderSpec; diff --git a/CPP/7zip/Archive/HandlerCont.h b/CPP/7zip/Archive/HandlerCont.h old mode 100644 new mode 100755 index 0b92d190c..3c645929b --- a/CPP/7zip/Archive/HandlerCont.h +++ b/CPP/7zip/Archive/HandlerCont.h @@ -94,7 +94,19 @@ class CHandlerImg: 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 old mode 100644 new mode 100755 index b70a291f8..f0a85f1ae --- 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 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Icons/apfs.ico b/CPP/7zip/Archive/Icons/apfs.ico new file mode 100755 index 0000000000000000000000000000000000000000..124eb76c30764d74e6b0a6a466633c8b103d4e4d GIT binary patch literal 3638 zcmeH}ze^lJ6o8-M0&-YrV`X71LhKHvvJ-p3#@cSke;`7Nt*iq9VXUr5LQwEWlI3Ob_HI_>DWm!M zqCbBu@&(&7)MaEHnGp=Ms^gbix(X-eswx+HhB6ooWbkz$SD)WXr_+(y*;$#Jo0Elw z1zB8Nl%=I5Sy@?;)zwwm-rknY%}v?Z*pRigHK|^xY;CE$k`vMISw5ZokduoGdHMbW zg#r?hgyfd&ZtIWbBHr=$gH9 zpbyj!BnnIlqT=Q00t^9$07HPmkzfcg1Q-Gg0S3o}A;1t|2rvW~936%LLx3T`5MT(3 z4UPauFb-8;0W4hYlaP#Hx1S74qCXys-Cu;lc z@Y>j^pQxXxZ?`B>Ke09mh6F=m9qhKTD*o%SaHY4~$QoqoW!N$tnRPz|^z^WApVBo$HyzUN;qNy-izyBpFrt|syN8%}G{1O@ ze`K7p{Ut+vqxt&%NqoaykNuXRu6d?ft#0`($#nmr`7NZm*kGK$nSa0E zAemVLr_A@L`~9t-GXnFOMVWj)OU=?3f4BG3z?)_svs+i9y4^N`yIKY7n!o2bpm(dk z+Z(kx%R1R6|K5{6(^|!R$Zj#i7V%G7Mb-iG4Y@+JF6R_Gx-283bISUi1Qll#0@>62 zLeKEwoWeVaR}}JaPI)+|aF%#Dr~GwpU=#h=y#M^QX*yf-=#{wF=&kM1{o~!SZggHO zeAvG4(%DgMSH({&(cb%eqNR6xL-SiQkB6YwYt{38yTwz^YixbCH?{@!u2$g~AlJxm DGvO#8 literal 0 HcmV?d00001 diff --git a/CPP/7zip/Archive/Icons/arj.ico b/CPP/7zip/Archive/Icons/arj.ico old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Icons/bz2.ico b/CPP/7zip/Archive/Icons/bz2.ico old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Icons/cab.ico b/CPP/7zip/Archive/Icons/cab.ico old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Icons/cpio.ico b/CPP/7zip/Archive/Icons/cpio.ico old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Icons/deb.ico b/CPP/7zip/Archive/Icons/deb.ico old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Icons/dmg.ico b/CPP/7zip/Archive/Icons/dmg.ico old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Icons/fat.ico b/CPP/7zip/Archive/Icons/fat.ico old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Icons/gz.ico b/CPP/7zip/Archive/Icons/gz.ico old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Icons/hfs.ico b/CPP/7zip/Archive/Icons/hfs.ico old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Icons/iso.ico b/CPP/7zip/Archive/Icons/iso.ico old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Icons/lzh.ico b/CPP/7zip/Archive/Icons/lzh.ico old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Icons/lzma.ico b/CPP/7zip/Archive/Icons/lzma.ico old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Icons/ntfs.ico b/CPP/7zip/Archive/Icons/ntfs.ico old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Icons/rar.ico b/CPP/7zip/Archive/Icons/rar.ico old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Icons/rpm.ico b/CPP/7zip/Archive/Icons/rpm.ico old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Icons/split.ico b/CPP/7zip/Archive/Icons/split.ico old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Icons/squashfs.ico b/CPP/7zip/Archive/Icons/squashfs.ico old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Icons/tar.ico b/CPP/7zip/Archive/Icons/tar.ico old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Icons/vhd.ico b/CPP/7zip/Archive/Icons/vhd.ico old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Icons/wim.ico b/CPP/7zip/Archive/Icons/wim.ico old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Icons/xar.ico b/CPP/7zip/Archive/Icons/xar.ico old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Icons/xz.ico b/CPP/7zip/Archive/Icons/xz.ico old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Icons/z.ico b/CPP/7zip/Archive/Icons/z.ico old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Icons/zip.ico b/CPP/7zip/Archive/Icons/zip.ico old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/IhexHandler.cpp b/CPP/7zip/Archive/IhexHandler.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Iso/IsoHandler.cpp b/CPP/7zip/Archive/Iso/IsoHandler.cpp old mode 100644 new mode 100755 index 87f4aa3be..8588a7c5b --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Iso/IsoHeader.cpp b/CPP/7zip/Archive/Iso/IsoHeader.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Iso/IsoHeader.h b/CPP/7zip/Archive/Iso/IsoHeader.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Iso/IsoIn.cpp b/CPP/7zip/Archive/Iso/IsoIn.cpp old mode 100644 new mode 100755 index 211b3eeae..678023592 --- 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 old mode 100644 new mode 100755 index 347f9e9b7..a705b06a8 --- 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 old mode 100644 new mode 100755 index a42ae0399..8c2a7253c --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Iso/StdAfx.h b/CPP/7zip/Archive/Iso/StdAfx.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/LpHandler.cpp b/CPP/7zip/Archive/LpHandler.cpp new file mode 100755 index 000000000..b2720f4bf --- /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 _items; + CRecordVector Extents; + + CMyComPtr _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 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 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 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 copyCoder = copyCoderSpec; + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr progress = lps; + lps->Init(extractCallback, false); + + for (i = 0; i < numItems; i++) + { + lps->InSize = totalSize; + lps->OutSize = totalSize; + RINOK(lps->SetCur()); + CMyComPtr 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 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 old mode 100644 new mode 100755 index e1984d283..6711da60a --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/MachoHandler.cpp b/CPP/7zip/Archive/MachoHandler.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/MbrHandler.cpp b/CPP/7zip/Archive/MbrHandler.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/MslzHandler.cpp b/CPP/7zip/Archive/MslzHandler.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/MubHandler.cpp b/CPP/7zip/Archive/MubHandler.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Nsis/NsisDecode.cpp b/CPP/7zip/Archive/Nsis/NsisDecode.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Nsis/NsisDecode.h b/CPP/7zip/Archive/Nsis/NsisDecode.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Nsis/NsisHandler.cpp b/CPP/7zip/Archive/Nsis/NsisHandler.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Nsis/NsisHandler.h b/CPP/7zip/Archive/Nsis/NsisHandler.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Nsis/NsisIn.cpp b/CPP/7zip/Archive/Nsis/NsisIn.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Nsis/NsisIn.h b/CPP/7zip/Archive/Nsis/NsisIn.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Nsis/NsisRegister.cpp b/CPP/7zip/Archive/Nsis/NsisRegister.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Nsis/StdAfx.h b/CPP/7zip/Archive/Nsis/StdAfx.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/NtfsHandler.cpp b/CPP/7zip/Archive/NtfsHandler.cpp old mode 100644 new mode 100755 index daa01fef4..7d0c6f780 --- 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 old mode 100644 new mode 100755 index ee265571f..34a38acf9 --- 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 old mode 100644 new mode 100755 index 05a07e53d..101bfd982 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Rar/Rar5Handler.cpp b/CPP/7zip/Archive/Rar/Rar5Handler.cpp old mode 100644 new mode 100755 index bb8a2edb2..563695f82 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Rar/RarHandler.cpp b/CPP/7zip/Archive/Rar/RarHandler.cpp old mode 100644 new mode 100755 index 7491c50b0..ecadf8533 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Rar/RarHeader.h b/CPP/7zip/Archive/Rar/RarHeader.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Rar/RarItem.h b/CPP/7zip/Archive/Rar/RarItem.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Rar/RarVol.h b/CPP/7zip/Archive/Rar/RarVol.h old mode 100644 new mode 100755 index 962643302..2f5bbd37d --- a/CPP/7zip/Archive/Rar/RarVol.h +++ b/CPP/7zip/Archive/Rar/RarVol.h @@ -52,7 +52,7 @@ class CVolumeName ext.IsEqualTo_Ascii_NoCase("r01")) { _changed = ext; - _before = name.Left(dotPos + 1); + _before.SetFrom(name.Ptr(), dotPos + 1); return true; } } @@ -60,16 +60,23 @@ class CVolumeName 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Rar/StdAfx.h b/CPP/7zip/Archive/Rar/StdAfx.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/RpmHandler.cpp b/CPP/7zip/Archive/RpmHandler.cpp old mode 100644 new mode 100755 index e0ec28ce1..366f8efb6 --- 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 000000000..47e3ed8de --- /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 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 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 old mode 100644 new mode 100755 index 6705aee05..6bddfb836 --- 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 old mode 100644 new mode 100755 index 74bc8fb80..fe271bc38 --- 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 _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 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/SwfHandler.cpp b/CPP/7zip/Archive/SwfHandler.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Tar/StdAfx.h b/CPP/7zip/Archive/Tar/StdAfx.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Tar/TarHandler.cpp b/CPP/7zip/Archive/Tar/TarHandler.cpp old mode 100644 new mode 100755 index 2f23dd85c..bd04bd7d2 --- 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 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 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 old mode 100644 new mode 100755 index 4834c2a71..44a99809f --- 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 @@ class CHandler: CMyComPtr _stream; CMyComPtr _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 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 old mode 100644 new mode 100755 index 5ddb4b244..53255e4c7 --- a/CPP/7zip/Archive/Tar/TarHandlerOut.cpp +++ b/CPP/7zip/Archive/Tar/TarHandlerOut.cpp @@ -2,15 +2,16 @@ #include "StdAfx.h" +// #include + #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 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 old mode 100644 new mode 100755 index 9c16c8956..f1efddb5a --- 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 old mode 100644 new mode 100755 index b0f0ec34f..1af30935f --- 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 old mode 100644 new mode 100755 index 58399d0ca..4fd8c5b15 --- 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 old mode 100644 new mode 100755 index 1c508bcce..e99599a4f --- 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 old mode 100644 new mode 100755 index f947786f1..738618f2f --- 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 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 old mode 100644 new mode 100755 index 271b854a7..f73c625b4 --- 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 old mode 100644 new mode 100755 index ee9b965ed..34af20ac3 --- a/CPP/7zip/Archive/Tar/TarOut.h +++ b/CPP/7zip/Archive/Tar/TarOut.h @@ -14,21 +14,38 @@ namespace NTar { class COutArchive { - CMyComPtr m_Stream; + CMyComPtr 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 old mode 100644 new mode 100755 index 5014f04df..a78c37662 --- 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 old mode 100644 new mode 100755 index 295e16bb5..caa0a8224 --- a/CPP/7zip/Archive/Tar/TarUpdate.cpp +++ b/CPP/7zip/Archive/Tar/TarUpdate.cpp @@ -2,6 +2,8 @@ #include "StdAfx.h" +// #include + #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 &inputItems, const CObjectVector &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 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 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 getProps; - fileInStream->QueryInterface(IID_IStreamGetProps, (void **)&getProps); - if (getProps) + CMyComPtr 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 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 old mode 100644 new mode 100755 index 1e3d02173..ca0976dd5 --- 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 &inputItems, const CObjectVector &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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Udf/UdfHandler.cpp b/CPP/7zip/Archive/Udf/UdfHandler.cpp old mode 100644 new mode 100755 index 74ec0beb4..2232c64a1 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Udf/UdfIn.cpp b/CPP/7zip/Archive/Udf/UdfIn.cpp old mode 100644 new mode 100755 index 04d9228f4..d2d2b20a3 --- 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 old mode 100644 new mode 100755 index c26f60994..4e7dfa11d --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/VdiHandler.cpp b/CPP/7zip/Archive/VdiHandler.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/VhdHandler.cpp b/CPP/7zip/Archive/VhdHandler.cpp old mode 100644 new mode 100755 index 8b9af45af..60bc3d301 --- 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 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 old mode 100644 new mode 100755 index e1e4692d8..0fc83acec --- 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 old mode 100644 new mode 100755 index fb5bb1f8e..40f561314 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Wim/WimHandler.cpp b/CPP/7zip/Archive/Wim/WimHandler.cpp old mode 100644 new mode 100755 index 9e39d028e..3b3945578 --- 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 @@ class CVolumeName 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Wim/WimHandlerOut.cpp b/CPP/7zip/Archive/Wim/WimHandlerOut.cpp old mode 100644 new mode 100755 index 6b4497feb..5e8365a48 --- 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 &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 &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 old mode 100644 new mode 100755 index fef6b34f0..f805521a4 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Wim/WimRegister.cpp b/CPP/7zip/Archive/Wim/WimRegister.cpp old mode 100644 new mode 100755 index ecebe8d94..e143f91ca --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/XzHandler.cpp b/CPP/7zip/Archive/XzHandler.cpp old mode 100644 new mode 100755 index f1afab668..d358ca565 --- 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 fileInStream; - RINOK(updateCallback->GetStream(0, &fileInStream)); - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(updateCallback, true); - - RINOK(encoderSpec->Code(fileInStream, outStream, NULL, NULL, progress)); - + { + CMyComPtr fileInStream; + RINOK(updateCallback->GetStream(0, &fileInStream)); + if (!fileInStream) + return S_FALSE; + { + CMyComPtr 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 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/ZHandler.cpp b/CPP/7zip/Archive/ZHandler.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Zip/StdAfx.h b/CPP/7zip/Archive/Zip/StdAfx.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Zip/ZipAddCommon.cpp b/CPP/7zip/Archive/Zip/ZipAddCommon.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Zip/ZipAddCommon.h b/CPP/7zip/Archive/Zip/ZipAddCommon.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Zip/ZipCompressionMode.h b/CPP/7zip/Archive/Zip/ZipCompressionMode.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Zip/ZipHandler.cpp b/CPP/7zip/Archive/Zip/ZipHandler.cpp old mode 100644 new mode 100755 index d8168bbec..1b3985fd2 --- 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 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 old mode 100644 new mode 100755 index 3043e41c3..a70a1a760 --- a/CPP/7zip/Archive/Zip/ZipHandler.h +++ b/CPP/7zip/Archive/Zip/ZipHandler.h @@ -57,7 +57,9 @@ class CHandler: int m_MainMethod; bool m_ForceAesMode; - bool m_WriteNtfsTimeExtra; + + CHandlerTimeOptions TimeOptions; + bool _removeSfxBlock; bool m_ForceLocal; bool m_ForceUtf8; @@ -71,7 +73,8 @@ class CHandler: _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 old mode 100644 new mode 100755 index a9b3eae5b..77a71df22 --- 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 old mode 100644 new mode 100755 index c47659acb..34fa359b1 --- 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 old mode 100644 new mode 100755 index 076d6bb57..f2b69a9cc --- 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 &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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Archive/Zip/ZipItem.cpp b/CPP/7zip/Archive/Zip/ZipItem.cpp old mode 100644 new mode 100755 index be3364853..cffbb78a4 --- 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 old mode 100644 new mode 100755 index 6ee876585..934d7ecf7 --- 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 old mode 100644 new mode 100755 index efed0a418..8f3f43bfd --- 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 &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 old mode 100644 new mode 100755 index 3546411ca..a645d67f7 --- a/CPP/7zip/Archive/Zip/ZipOut.h +++ b/CPP/7zip/Archive/Zip/ZipOut.h @@ -18,7 +18,8 @@ class CItemOut: public CItem 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 @@ class CItemOut: public CItem 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 old mode 100644 new mode 100755 index e6929f1b0..3ad47153d --- 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 old mode 100644 new mode 100755 index 26636c78a..7f13071a4 --- 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 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 &inputItems, CObjectVector &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 progress = lps; @@ -575,7 +638,8 @@ static HRESULT Update2St( } else { - CMyComPtr fileInStream; + CMyComPtr 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 &inputItems, CObjectVector &updateItems, + const CUpdateOptions &updateOptions, const CCompressionMethodMode &options, bool outSeqMode, const CByteBuffer *comment, IArchiveUpdateCallback *updateCallback) @@ -674,6 +748,11 @@ static HRESULT Update2( CMyComPtr opCallback; updateCallback->QueryInterface(IID_IArchiveUpdateCallbackFile, (void **)&opCallback); + /* + CMyComPtr 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 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 &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 old mode 100644 new mode 100755 index 95e72a47a..d1e353478 --- 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 &inputItems, CObjectVector &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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Asm.mak b/CPP/7zip/Asm.mak old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Alone/Alone.dsp b/CPP/7zip/Bundles/Alone/Alone.dsp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Alone/Alone.dsw b/CPP/7zip/Bundles/Alone/Alone.dsw old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Alone/StdAfx.cpp b/CPP/7zip/Bundles/Alone/StdAfx.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Alone/StdAfx.h b/CPP/7zip/Bundles/Alone/StdAfx.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Alone/afxres.h b/CPP/7zip/Bundles/Alone/afxres.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Alone/makefile b/CPP/7zip/Bundles/Alone/makefile old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Alone/makefile.gcc b/CPP/7zip/Bundles/Alone/makefile.gcc old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Alone/resource.rc b/CPP/7zip/Bundles/Alone/resource.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Alone2/StdAfx.cpp b/CPP/7zip/Bundles/Alone2/StdAfx.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Alone2/StdAfx.h b/CPP/7zip/Bundles/Alone2/StdAfx.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Alone2/makefile b/CPP/7zip/Bundles/Alone2/makefile old mode 100644 new mode 100755 index 56de5b2ec..357e78ee2 --- 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 old mode 100644 new mode 100755 index 1e7e17f17..f8d31dba4 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Alone7z/Alone.dsp b/CPP/7zip/Bundles/Alone7z/Alone.dsp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Alone7z/Alone.dsw b/CPP/7zip/Bundles/Alone7z/Alone.dsw old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Alone7z/StdAfx.cpp b/CPP/7zip/Bundles/Alone7z/StdAfx.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Alone7z/StdAfx.h b/CPP/7zip/Bundles/Alone7z/StdAfx.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Alone7z/makefile b/CPP/7zip/Bundles/Alone7z/makefile old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Alone7z/makefile.gcc b/CPP/7zip/Bundles/Alone7z/makefile.gcc old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Alone7z/resource.rc b/CPP/7zip/Bundles/Alone7z/resource.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Fm/FM.dsp b/CPP/7zip/Bundles/Fm/FM.dsp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Fm/FM.dsw b/CPP/7zip/Bundles/Fm/FM.dsw old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Fm/StdAfx.cpp b/CPP/7zip/Bundles/Fm/StdAfx.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Fm/StdAfx.h b/CPP/7zip/Bundles/Fm/StdAfx.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Fm/makefile b/CPP/7zip/Bundles/Fm/makefile old mode 100644 new mode 100755 index 2c80ca1d7..33813e82f --- 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 old mode 100644 new mode 100755 index ffcff11a3..ebc2f74bc --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Format7z/StdAfx.h b/CPP/7zip/Bundles/Format7z/StdAfx.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Format7z/makefile b/CPP/7zip/Bundles/Format7z/makefile old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Format7z/resource.rc b/CPP/7zip/Bundles/Format7z/resource.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Format7zExtract/StdAfx.cpp b/CPP/7zip/Bundles/Format7zExtract/StdAfx.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Format7zExtract/StdAfx.h b/CPP/7zip/Bundles/Format7zExtract/StdAfx.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Format7zExtract/makefile b/CPP/7zip/Bundles/Format7zExtract/makefile old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Format7zExtract/resource.rc b/CPP/7zip/Bundles/Format7zExtract/resource.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Format7zExtractR/StdAfx.cpp b/CPP/7zip/Bundles/Format7zExtractR/StdAfx.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Format7zExtractR/StdAfx.h b/CPP/7zip/Bundles/Format7zExtractR/StdAfx.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Format7zExtractR/makefile b/CPP/7zip/Bundles/Format7zExtractR/makefile old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Format7zExtractR/resource.rc b/CPP/7zip/Bundles/Format7zExtractR/resource.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Format7zF/Arc.mak b/CPP/7zip/Bundles/Format7zF/Arc.mak old mode 100644 new mode 100755 index d8468a6f7..209aea324 --- 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 old mode 100644 new mode 100755 index 8021f68ac..e5e1e21b9 --- 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 old mode 100644 new mode 100755 index 6b55e93d9..cf2d9e863 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Format7zF/StdAfx.cpp b/CPP/7zip/Bundles/Format7zF/StdAfx.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Format7zF/StdAfx.h b/CPP/7zip/Bundles/Format7zF/StdAfx.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Format7zF/makefile b/CPP/7zip/Bundles/Format7zF/makefile old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Format7zF/makefile.gcc b/CPP/7zip/Bundles/Format7zF/makefile.gcc old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Format7zF/resource.rc b/CPP/7zip/Bundles/Format7zF/resource.rc old mode 100644 new mode 100755 index aaaabeaae..9c797c156 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Format7zR/StdAfx.h b/CPP/7zip/Bundles/Format7zR/StdAfx.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Format7zR/makefile b/CPP/7zip/Bundles/Format7zR/makefile old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/Format7zR/resource.rc b/CPP/7zip/Bundles/Format7zR/resource.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp b/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp old mode 100644 new mode 100755 index a08d9c091..71436f658 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsw b/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsw old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/LzmaCon/StdAfx.cpp b/CPP/7zip/Bundles/LzmaCon/StdAfx.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/LzmaCon/StdAfx.h b/CPP/7zip/Bundles/LzmaCon/StdAfx.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/LzmaCon/makefile b/CPP/7zip/Bundles/LzmaCon/makefile old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/LzmaCon/makefile.gcc b/CPP/7zip/Bundles/LzmaCon/makefile.gcc old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/LzmaCon/resource.rc b/CPP/7zip/Bundles/LzmaCon/resource.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/SFXCon/7z.ico b/CPP/7zip/Bundles/SFXCon/7z.ico old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/SFXCon/SFXCon.dsp b/CPP/7zip/Bundles/SFXCon/SFXCon.dsp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/SFXCon/SFXCon.dsw b/CPP/7zip/Bundles/SFXCon/SFXCon.dsw old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/SFXCon/SfxCon.cpp b/CPP/7zip/Bundles/SFXCon/SfxCon.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/SFXCon/StdAfx.cpp b/CPP/7zip/Bundles/SFXCon/StdAfx.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/SFXCon/StdAfx.h b/CPP/7zip/Bundles/SFXCon/StdAfx.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/SFXCon/makefile b/CPP/7zip/Bundles/SFXCon/makefile old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/SFXCon/makefile.gcc b/CPP/7zip/Bundles/SFXCon/makefile.gcc old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/SFXCon/resource.rc b/CPP/7zip/Bundles/SFXCon/resource.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp b/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.h b/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp b/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/SFXSetup/ExtractEngine.h b/CPP/7zip/Bundles/SFXSetup/ExtractEngine.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp b/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsw b/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsw old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp b/CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/SFXSetup/StdAfx.cpp b/CPP/7zip/Bundles/SFXSetup/StdAfx.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/SFXSetup/StdAfx.h b/CPP/7zip/Bundles/SFXSetup/StdAfx.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/SFXSetup/makefile b/CPP/7zip/Bundles/SFXSetup/makefile old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/SFXSetup/resource.h b/CPP/7zip/Bundles/SFXSetup/resource.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/SFXSetup/resource.rc b/CPP/7zip/Bundles/SFXSetup/resource.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/SFXSetup/setup.ico b/CPP/7zip/Bundles/SFXSetup/setup.ico old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/SFXWin/7z.ico b/CPP/7zip/Bundles/SFXWin/7z.ico old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/SFXWin/SFXWin.dsp b/CPP/7zip/Bundles/SFXWin/SFXWin.dsp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/SFXWin/SFXWin.dsw b/CPP/7zip/Bundles/SFXWin/SFXWin.dsw old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/SFXWin/SfxWin.cpp b/CPP/7zip/Bundles/SFXWin/SfxWin.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/SFXWin/StdAfx.cpp b/CPP/7zip/Bundles/SFXWin/StdAfx.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/SFXWin/StdAfx.h b/CPP/7zip/Bundles/SFXWin/StdAfx.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/SFXWin/makefile b/CPP/7zip/Bundles/SFXWin/makefile old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/SFXWin/resource.h b/CPP/7zip/Bundles/SFXWin/resource.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/SFXWin/resource.rc b/CPP/7zip/Bundles/SFXWin/resource.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/Bundles/makefile b/CPP/7zip/Bundles/makefile old mode 100644 new mode 100755 diff --git a/CPP/7zip/Common/CWrappers.cpp b/CPP/7zip/Common/CWrappers.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Common/CWrappers.h b/CPP/7zip/Common/CWrappers.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Common/CreateCoder.cpp b/CPP/7zip/Common/CreateCoder.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Common/CreateCoder.h b/CPP/7zip/Common/CreateCoder.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Common/FilePathAutoRename.cpp b/CPP/7zip/Common/FilePathAutoRename.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Common/FilePathAutoRename.h b/CPP/7zip/Common/FilePathAutoRename.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Common/FileStreams.cpp b/CPP/7zip/Common/FileStreams.cpp old mode 100644 new mode 100755 index 9e0e79cae..6862a9b6e --- a/CPP/7zip/Common/FileStreams.cpp +++ b/CPP/7zip/Common/FileStreams.cpp @@ -2,18 +2,30 @@ #include "StdAfx.h" +// #include + #ifndef _WIN32 #include #include #include -#include "../../Windows/FileFind.h" +#include +#include + +// for major minor +// BSD: +#include + #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 old mode 100644 new mode 100755 index fe9f4c199..f2c19eea1 --- 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 @@ class CInFileStream: #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 @@ class CInFileStream: 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 @@ class CInFileStream: 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 @@ class COutFileStream: 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Common/FilterCoder.h b/CPP/7zip/Common/FilterCoder.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Common/InBuffer.cpp b/CPP/7zip/Common/InBuffer.cpp old mode 100644 new mode 100755 index 6f6eecad7..fe6d14902 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Common/InOutTempBuffer.cpp b/CPP/7zip/Common/InOutTempBuffer.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Common/InOutTempBuffer.h b/CPP/7zip/Common/InOutTempBuffer.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Common/LimitedStreams.cpp b/CPP/7zip/Common/LimitedStreams.cpp old mode 100644 new mode 100755 index add6636b7..980c795d2 --- 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 old mode 100644 new mode 100755 index ade299378..50c7cd853 --- a/CPP/7zip/Common/LimitedStreams.h +++ b/CPP/7zip/Common/LimitedStreams.h @@ -101,21 +101,26 @@ class CClusterInStream: 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 Stream; @@ -129,11 +134,13 @@ class CExtentsStream: 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Common/LockedStream.h b/CPP/7zip/Common/LockedStream.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Common/MemBlocks.cpp b/CPP/7zip/Common/MemBlocks.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Common/MemBlocks.h b/CPP/7zip/Common/MemBlocks.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Common/MethodId.cpp b/CPP/7zip/Common/MethodId.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Common/MethodId.h b/CPP/7zip/Common/MethodId.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Common/MethodProps.cpp b/CPP/7zip/Common/MethodProps.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Common/MethodProps.h b/CPP/7zip/Common/MethodProps.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Common/OffsetStream.cpp b/CPP/7zip/Common/OffsetStream.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Common/OffsetStream.h b/CPP/7zip/Common/OffsetStream.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Common/OutBuffer.cpp b/CPP/7zip/Common/OutBuffer.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Common/OutBuffer.h b/CPP/7zip/Common/OutBuffer.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Common/OutMemStream.cpp b/CPP/7zip/Common/OutMemStream.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Common/OutMemStream.h b/CPP/7zip/Common/OutMemStream.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Common/ProgressMt.cpp b/CPP/7zip/Common/ProgressMt.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Common/ProgressMt.h b/CPP/7zip/Common/ProgressMt.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Common/ProgressUtils.cpp b/CPP/7zip/Common/ProgressUtils.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Common/ProgressUtils.h b/CPP/7zip/Common/ProgressUtils.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Common/PropId.cpp b/CPP/7zip/Common/PropId.cpp old mode 100644 new mode 100755 index 11d20d557..0e643e853 --- 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 old mode 100644 new mode 100755 index 3421ba1b1..a0384fad6 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Common/StdAfx.h b/CPP/7zip/Common/StdAfx.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Common/StreamBinder.cpp b/CPP/7zip/Common/StreamBinder.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Common/StreamBinder.h b/CPP/7zip/Common/StreamBinder.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Common/StreamObjects.cpp b/CPP/7zip/Common/StreamObjects.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Common/StreamObjects.h b/CPP/7zip/Common/StreamObjects.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Common/StreamUtils.cpp b/CPP/7zip/Common/StreamUtils.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Common/StreamUtils.h b/CPP/7zip/Common/StreamUtils.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Common/UniqBlocks.cpp b/CPP/7zip/Common/UniqBlocks.cpp old mode 100644 new mode 100755 index 8f754e177..32dc27626 --- 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 old mode 100644 new mode 100755 index d6cd3728b..8479d68cb --- 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 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Common/VirtThread.h b/CPP/7zip/Common/VirtThread.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/BZip2Const.h b/CPP/7zip/Compress/BZip2Const.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/BZip2Crc.cpp b/CPP/7zip/Compress/BZip2Crc.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/BZip2Crc.h b/CPP/7zip/Compress/BZip2Crc.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/BZip2Decoder.cpp b/CPP/7zip/Compress/BZip2Decoder.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/BZip2Decoder.h b/CPP/7zip/Compress/BZip2Decoder.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/BZip2Encoder.cpp b/CPP/7zip/Compress/BZip2Encoder.cpp old mode 100644 new mode 100755 index 25c3f045e..62c15d67c --- 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 old mode 100644 new mode 100755 index 5e63a730b..e2828a922 --- a/CPP/7zip/Compress/BZip2Encoder.h +++ b/CPP/7zip/Compress/BZip2Encoder.h @@ -129,7 +129,7 @@ class CThreadInfo // 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 @@ class CEncoder : 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/Bcj2Coder.cpp b/CPP/7zip/Compress/Bcj2Coder.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/Bcj2Coder.h b/CPP/7zip/Compress/Bcj2Coder.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/Bcj2Register.cpp b/CPP/7zip/Compress/Bcj2Register.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/BcjCoder.cpp b/CPP/7zip/Compress/BcjCoder.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/BcjCoder.h b/CPP/7zip/Compress/BcjCoder.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/BcjRegister.cpp b/CPP/7zip/Compress/BcjRegister.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/BitlDecoder.cpp b/CPP/7zip/Compress/BitlDecoder.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/BitlDecoder.h b/CPP/7zip/Compress/BitlDecoder.h old mode 100644 new mode 100755 index e85942cf2..825864d8a --- a/CPP/7zip/Compress/BitlDecoder.h +++ b/CPP/7zip/Compress/BitlDecoder.h @@ -155,6 +155,10 @@ class CDecoder: public CBaseDecoder 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/BitmDecoder.h b/CPP/7zip/Compress/BitmDecoder.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/BitmEncoder.h b/CPP/7zip/Compress/BitmEncoder.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/BranchMisc.cpp b/CPP/7zip/Compress/BranchMisc.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/BranchMisc.h b/CPP/7zip/Compress/BranchMisc.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/BranchRegister.cpp b/CPP/7zip/Compress/BranchRegister.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/ByteSwap.cpp b/CPP/7zip/Compress/ByteSwap.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/Codec.def b/CPP/7zip/Compress/Codec.def old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/CodecExports.cpp b/CPP/7zip/Compress/CodecExports.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/CopyCoder.cpp b/CPP/7zip/Compress/CopyCoder.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/CopyCoder.h b/CPP/7zip/Compress/CopyCoder.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/CopyRegister.cpp b/CPP/7zip/Compress/CopyRegister.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/Deflate64Register.cpp b/CPP/7zip/Compress/Deflate64Register.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/DeflateConst.h b/CPP/7zip/Compress/DeflateConst.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/DeflateDecoder.cpp b/CPP/7zip/Compress/DeflateDecoder.cpp old mode 100644 new mode 100755 index 0206ce8dd..e4f66b7d3 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/DeflateEncoder.cpp b/CPP/7zip/Compress/DeflateEncoder.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/DeflateEncoder.h b/CPP/7zip/Compress/DeflateEncoder.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/DeflateRegister.cpp b/CPP/7zip/Compress/DeflateRegister.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/DeltaFilter.cpp b/CPP/7zip/Compress/DeltaFilter.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/DllExports2Compress.cpp b/CPP/7zip/Compress/DllExports2Compress.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/DllExportsCompress.cpp b/CPP/7zip/Compress/DllExportsCompress.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/HuffmanDecoder.h b/CPP/7zip/Compress/HuffmanDecoder.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/ImplodeDecoder.cpp b/CPP/7zip/Compress/ImplodeDecoder.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/ImplodeDecoder.h b/CPP/7zip/Compress/ImplodeDecoder.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp b/CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/ImplodeHuffmanDecoder.h b/CPP/7zip/Compress/ImplodeHuffmanDecoder.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/LzOutWindow.cpp b/CPP/7zip/Compress/LzOutWindow.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/LzOutWindow.h b/CPP/7zip/Compress/LzOutWindow.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/LzfseDecoder.cpp b/CPP/7zip/Compress/LzfseDecoder.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/LzfseDecoder.h b/CPP/7zip/Compress/LzfseDecoder.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/LzhDecoder.cpp b/CPP/7zip/Compress/LzhDecoder.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/LzhDecoder.h b/CPP/7zip/Compress/LzhDecoder.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/Lzma2Decoder.cpp b/CPP/7zip/Compress/Lzma2Decoder.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/Lzma2Decoder.h b/CPP/7zip/Compress/Lzma2Decoder.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/Lzma2Encoder.cpp b/CPP/7zip/Compress/Lzma2Encoder.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/Lzma2Encoder.h b/CPP/7zip/Compress/Lzma2Encoder.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/Lzma2Register.cpp b/CPP/7zip/Compress/Lzma2Register.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/LzmaDecoder.cpp b/CPP/7zip/Compress/LzmaDecoder.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/LzmaDecoder.h b/CPP/7zip/Compress/LzmaDecoder.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/LzmaEncoder.cpp b/CPP/7zip/Compress/LzmaEncoder.cpp old mode 100644 new mode 100755 index 4b3acd307..dabd77a0f --- 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 +#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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/LzmaRegister.cpp b/CPP/7zip/Compress/LzmaRegister.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/LzmsDecoder.cpp b/CPP/7zip/Compress/LzmsDecoder.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/LzmsDecoder.h b/CPP/7zip/Compress/LzmsDecoder.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/Lzx.h b/CPP/7zip/Compress/Lzx.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/LzxDecoder.cpp b/CPP/7zip/Compress/LzxDecoder.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/LzxDecoder.h b/CPP/7zip/Compress/LzxDecoder.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/Mtf8.h b/CPP/7zip/Compress/Mtf8.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/PpmdDecoder.cpp b/CPP/7zip/Compress/PpmdDecoder.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/PpmdDecoder.h b/CPP/7zip/Compress/PpmdDecoder.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/PpmdEncoder.cpp b/CPP/7zip/Compress/PpmdEncoder.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/PpmdEncoder.h b/CPP/7zip/Compress/PpmdEncoder.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/PpmdRegister.cpp b/CPP/7zip/Compress/PpmdRegister.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/PpmdZip.cpp b/CPP/7zip/Compress/PpmdZip.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/PpmdZip.h b/CPP/7zip/Compress/PpmdZip.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/QuantumDecoder.cpp b/CPP/7zip/Compress/QuantumDecoder.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/QuantumDecoder.h b/CPP/7zip/Compress/QuantumDecoder.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/Rar1Decoder.cpp b/CPP/7zip/Compress/Rar1Decoder.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/Rar1Decoder.h b/CPP/7zip/Compress/Rar1Decoder.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/Rar2Decoder.cpp b/CPP/7zip/Compress/Rar2Decoder.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/Rar2Decoder.h b/CPP/7zip/Compress/Rar2Decoder.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/Rar3Decoder.cpp b/CPP/7zip/Compress/Rar3Decoder.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/Rar3Decoder.h b/CPP/7zip/Compress/Rar3Decoder.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/Rar3Vm.cpp b/CPP/7zip/Compress/Rar3Vm.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/Rar3Vm.h b/CPP/7zip/Compress/Rar3Vm.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/Rar5Decoder.cpp b/CPP/7zip/Compress/Rar5Decoder.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/Rar5Decoder.h b/CPP/7zip/Compress/Rar5Decoder.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/RarCodecsRegister.cpp b/CPP/7zip/Compress/RarCodecsRegister.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/ShrinkDecoder.cpp b/CPP/7zip/Compress/ShrinkDecoder.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/ShrinkDecoder.h b/CPP/7zip/Compress/ShrinkDecoder.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/StdAfx.h b/CPP/7zip/Compress/StdAfx.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/XpressDecoder.cpp b/CPP/7zip/Compress/XpressDecoder.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/XpressDecoder.h b/CPP/7zip/Compress/XpressDecoder.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/XzDecoder.cpp b/CPP/7zip/Compress/XzDecoder.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/XzDecoder.h b/CPP/7zip/Compress/XzDecoder.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/XzEncoder.cpp b/CPP/7zip/Compress/XzEncoder.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/XzEncoder.h b/CPP/7zip/Compress/XzEncoder.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/ZDecoder.cpp b/CPP/7zip/Compress/ZDecoder.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/ZDecoder.h b/CPP/7zip/Compress/ZDecoder.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/ZlibDecoder.cpp b/CPP/7zip/Compress/ZlibDecoder.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/ZlibDecoder.h b/CPP/7zip/Compress/ZlibDecoder.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/ZlibEncoder.cpp b/CPP/7zip/Compress/ZlibEncoder.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/ZlibEncoder.h b/CPP/7zip/Compress/ZlibEncoder.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Compress/makefile b/CPP/7zip/Compress/makefile old mode 100644 new mode 100755 diff --git a/CPP/7zip/Crc.mak b/CPP/7zip/Crc.mak old mode 100644 new mode 100755 diff --git a/CPP/7zip/Crc64.mak b/CPP/7zip/Crc64.mak old mode 100644 new mode 100755 diff --git a/CPP/7zip/Crypto/7zAes.cpp b/CPP/7zip/Crypto/7zAes.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Crypto/7zAes.h b/CPP/7zip/Crypto/7zAes.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Crypto/7zAesRegister.cpp b/CPP/7zip/Crypto/7zAesRegister.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Crypto/Codec.def b/CPP/7zip/Crypto/Codec.def old mode 100644 new mode 100755 diff --git a/CPP/7zip/Crypto/HmacSha1.cpp b/CPP/7zip/Crypto/HmacSha1.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Crypto/HmacSha1.h b/CPP/7zip/Crypto/HmacSha1.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Crypto/HmacSha256.cpp b/CPP/7zip/Crypto/HmacSha256.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Crypto/HmacSha256.h b/CPP/7zip/Crypto/HmacSha256.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Crypto/MyAes.cpp b/CPP/7zip/Crypto/MyAes.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Crypto/MyAes.h b/CPP/7zip/Crypto/MyAes.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Crypto/MyAesReg.cpp b/CPP/7zip/Crypto/MyAesReg.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp b/CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Crypto/Pbkdf2HmacSha1.h b/CPP/7zip/Crypto/Pbkdf2HmacSha1.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Crypto/RandGen.cpp b/CPP/7zip/Crypto/RandGen.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Crypto/RandGen.h b/CPP/7zip/Crypto/RandGen.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Crypto/Rar20Crypto.cpp b/CPP/7zip/Crypto/Rar20Crypto.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Crypto/Rar20Crypto.h b/CPP/7zip/Crypto/Rar20Crypto.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Crypto/Rar5Aes.cpp b/CPP/7zip/Crypto/Rar5Aes.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Crypto/Rar5Aes.h b/CPP/7zip/Crypto/Rar5Aes.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Crypto/RarAes.cpp b/CPP/7zip/Crypto/RarAes.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Crypto/RarAes.h b/CPP/7zip/Crypto/RarAes.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Crypto/Sha1Cls.h b/CPP/7zip/Crypto/Sha1Cls.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Crypto/StdAfx.h b/CPP/7zip/Crypto/StdAfx.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Crypto/WzAes.cpp b/CPP/7zip/Crypto/WzAes.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Crypto/WzAes.h b/CPP/7zip/Crypto/WzAes.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Crypto/ZipCrypto.cpp b/CPP/7zip/Crypto/ZipCrypto.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Crypto/ZipCrypto.h b/CPP/7zip/Crypto/ZipCrypto.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/Crypto/ZipStrong.cpp b/CPP/7zip/Crypto/ZipStrong.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/Crypto/ZipStrong.h b/CPP/7zip/Crypto/ZipStrong.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/GuiCommon.rc b/CPP/7zip/GuiCommon.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/Guid.txt b/CPP/7zip/Guid.txt old mode 100644 new mode 100755 index 3b654bc89..8fcdd849d --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/IDecl.h b/CPP/7zip/IDecl.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/IPassword.h b/CPP/7zip/IPassword.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/IProgress.h b/CPP/7zip/IProgress.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/IStream.h b/CPP/7zip/IStream.h old mode 100644 new mode 100755 index 48c67c1aa..2793a1e9b --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/LzmaDec.mak b/CPP/7zip/LzmaDec.mak old mode 100644 new mode 100755 diff --git a/CPP/7zip/LzmaDec_gcc.mak b/CPP/7zip/LzmaDec_gcc.mak old mode 100644 new mode 100755 diff --git a/CPP/7zip/MyVersion.h b/CPP/7zip/MyVersion.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/MyVersionInfo.rc b/CPP/7zip/MyVersionInfo.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/PropID.h b/CPP/7zip/PropID.h old mode 100644 new mode 100755 index b818954fa..2da636fa3 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/Sha256.mak b/CPP/7zip/Sha256.mak old mode 100644 new mode 100755 diff --git a/CPP/7zip/SubBuild.mak b/CPP/7zip/SubBuild.mak old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Agent/Agent.cpp b/CPP/7zip/UI/Agent/Agent.cpp old mode 100644 new mode 100755 index cdb0e5d14..cc20c1160 --- 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 old mode 100644 new mode 100755 index e9fe41038..8e8a4c7d5 --- 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 @@ class CAgentFolder: 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 @@ class CAgentFolder: 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 @@ class CAgentFolder: _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 @@ class CAgentFolder: 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 old mode 100644 new mode 100755 index fae0e224d..da8da6cd6 --- 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 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 old mode 100644 new mode 100755 index f0acd20b0..4c9c386b1 --- 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(¤tItemIndex)); } @@ -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 old mode 100644 new mode 100755 index f2cb3d7ab..233174b42 --- 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 @@ class CProxyArc2 { 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 old mode 100644 new mode 100755 index a20b4f240..eca02ba1e --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Agent/ArchiveFolderOut.cpp b/CPP/7zip/UI/Agent/ArchiveFolderOut.cpp old mode 100644 new mode 100755 index 4a10ebecc..cd18c996f --- 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 old mode 100644 new mode 100755 index 565e37b00..92eb61601 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp b/CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Agent/UpdateCallbackAgent.h b/CPP/7zip/UI/Agent/UpdateCallbackAgent.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Client7z/Client7z.cpp b/CPP/7zip/UI/Client7z/Client7z.cpp old mode 100644 new mode 100755 index 0fa4cdadb..a55fa22d6 --- 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 @@ class CArchiveExtractCallback: 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 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Client7z/Client7z.dsw b/CPP/7zip/UI/Client7z/Client7z.dsw old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Client7z/StdAfx.cpp b/CPP/7zip/UI/Client7z/StdAfx.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Client7z/StdAfx.h b/CPP/7zip/UI/Client7z/StdAfx.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Client7z/makefile b/CPP/7zip/UI/Client7z/makefile old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Client7z/makefile.gcc b/CPP/7zip/UI/Client7z/makefile.gcc old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Client7z/resource.rc b/CPP/7zip/UI/Client7z/resource.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Common/ArchiveCommandLine.cpp b/CPP/7zip/UI/Common/ArchiveCommandLine.cpp old mode 100644 new mode 100755 index 91ef0382e..d88c8516e --- 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 old mode 100644 new mode 100755 index ff4f28ca8..745f999dd --- 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 old mode 100644 new mode 100755 index 73c191e44..a574f136e --- 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 *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(CMyComPtrIsItemAnti(index, isAnti)); + RINOK(_arc->IsItem_Anti(index, isAnti)); CorrectPathParts(); UString processedPath (MakePathFromParts(_item.PathParts)); @@ -1147,8 +1304,8 @@ HRESULT CArchiveExtractCallback::GetExtractStream(CMyComPtr= 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= 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 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 old mode 100644 new mode 100755 index fe9cb32eb..fe70bc92d --- 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 @@ class CArchiveExtractCallback: 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 @@ class CArchiveExtractCallback: 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 @@ class CArchiveExtractCallback: #endif + void InitBeforeNewArchive(); + void Init( const CExtractNtOptions &ntOptions, const NWildcard::CCensorNode *wildcardCensor, @@ -483,6 +533,7 @@ class CArchiveExtractCallback: 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Common/ArchiveName.h b/CPP/7zip/UI/Common/ArchiveName.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp b/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp old mode 100644 new mode 100755 index d5926f8fa..64aa98785 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Common/Bench.cpp b/CPP/7zip/UI/Common/Bench.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Common/Bench.h b/CPP/7zip/UI/Common/Bench.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Common/CompressCall.cpp b/CPP/7zip/UI/Common/CompressCall.cpp old mode 100644 new mode 100755 index c7efa99e7..3ef047f43 --- 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 ¶ms, 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 old mode 100644 new mode 100755 index b817df0f6..2697fda5f --- 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 old mode 100644 new mode 100755 index 762342d63..5d617e142 --- 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 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Common/DefaultName.h b/CPP/7zip/UI/Common/DefaultName.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Common/DirItem.h b/CPP/7zip/UI/Common/DirItem.h old mode 100644 new mode 100755 index e5f578dd0..86e385fe7 --- 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 @@ class CDirItems bool ScanAltStreams; bool ExcludeDirItems; bool ExcludeFileItems; + bool ShareForWrite; /* it must be called after anotrher checks */ bool CanIncludeItem(bool isDir) const @@ -160,7 +326,7 @@ class CDirItems const FString &phyPrefix); #endif - #if defined(_WIN32) && !defined(UNDER_CE) + #if defined(_WIN32) && !defined(UNDER_CE) CUniqBlocks SecureBlocks; CByteBuffer TempSecureBuf; @@ -170,7 +336,17 @@ class CDirItems 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 @@ class CDirItems }; + + 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 old mode 100644 new mode 100755 index 89cce2bab..a4ac413f5 --- a/CPP/7zip/UI/Common/EnumDirItems.cpp +++ b/CPP/7zip/UI/Common/EnumDirItems.cpp @@ -5,6 +5,12 @@ #include // #include +#ifndef _WIN32 +#include +#include +#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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Common/ExitCode.h b/CPP/7zip/UI/Common/ExitCode.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Common/Extract.cpp b/CPP/7zip/UI/Common/Extract.cpp old mode 100644 new mode 100755 index de2aeb26b..58f5218b6 --- 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 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 old mode 100644 new mode 100755 index 10e06dad0..f3d1126b7 --- 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 old mode 100644 new mode 100755 index 3b2b9a02e..9ad831eb7 --- 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 old mode 100644 new mode 100755 index 21a306d24..a1282b722 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Common/HashCalc.cpp b/CPP/7zip/UI/Common/HashCalc.cpp old mode 100644 new mode 100755 index 241770852..f0aa4bd14 --- 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 reportArcProp; + callback->QueryInterface(IID_IArchiveUpdateCallbackArcProp, (void **)&reportArcProp); + */ + CObjectVector 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 fileInStream; bool needWrite = true; { @@ -1840,6 +1862,15 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt if (fileInStream) { + CMyComPtr streamGetSize; + fileInStream->QueryInterface(IID_IStreamGetSize, (void **)&streamGetSize); + if (streamGetSize) + { + UInt64 size; + if (streamGetSize->GetSize(&size) == S_OK) + currentComplexity = size; + } + /* CMyComPtr 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 old mode 100644 new mode 100755 index 80a556537..c566caa88 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Common/LoadCodecs.cpp b/CPP/7zip/UI/Common/LoadCodecs.cpp old mode 100644 new mode 100755 index 377963aae..b6a207323 --- 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 old mode 100644 new mode 100755 index 829472d01..50fb9f8f5 --- 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 @@ class CCodecs: CRecordVector 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 old mode 100644 new mode 100755 index 331793f1a..4a91a2686 --- 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 old mode 100644 new mode 100755 index 4e1192cf0..e3220b94f --- 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 &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 @@ class CArc 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 @@ class CArc // void Set_ErrorFlagsText(); CArc(): - MTimeDefined(false), + // MTime_Defined(false), IsTree(false), IsReadOnly(false), Ask_Deleted(false), @@ -343,17 +349,29 @@ class CArc 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 old mode 100644 new mode 100755 index 30efd53bf..72384b3ef --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Common/Property.h b/CPP/7zip/UI/Common/Property.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Common/SetProperties.cpp b/CPP/7zip/UI/Common/SetProperties.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Common/SetProperties.h b/CPP/7zip/UI/Common/SetProperties.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Common/SortUtils.cpp b/CPP/7zip/UI/Common/SortUtils.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Common/SortUtils.h b/CPP/7zip/UI/Common/SortUtils.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Common/StdAfx.h b/CPP/7zip/UI/Common/StdAfx.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Common/TempFiles.cpp b/CPP/7zip/UI/Common/TempFiles.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Common/TempFiles.h b/CPP/7zip/UI/Common/TempFiles.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Common/Update.cpp b/CPP/7zip/UI/Common/Update.cpp old mode 100644 new mode 100755 index 032a876d9..042991d19 --- a/CPP/7zip/UI/Common/Update.cpp +++ b/CPP/7zip/UI/Common/Update.cpp @@ -2,6 +2,8 @@ #include "StdAfx.h" +// #include + #include "Update.h" #include "../../../Common/StringConvert.h" @@ -101,7 +103,7 @@ class COutMultiVolStream: _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 outSeekStream; CMyComPtr 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 old mode 100644 new mode 100755 index 06d13877d..01fc43e23 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Common/UpdateAction.h b/CPP/7zip/UI/Common/UpdateAction.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Common/UpdateCallback.cpp b/CPP/7zip/UI/Common/UpdateCallback.cpp old mode 100644 new mode 100755 index 7b705ba37..926a275d4 --- a/CPP/7zip/UI/Common/UpdateCallback.cpp +++ b/CPP/7zip/UI/Common/UpdateCallback.cpp @@ -4,6 +4,15 @@ // #include +#ifndef _WIN32 +// #include +// #include + +// for major minor: +// BSD: +#include +#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 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 old mode 100644 new mode 100755 index d27776ef6..3719c1ea6 --- 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 @@ class CArchiveUpdateCallback: INTERFACE_IArchiveUpdateCallback2(;) INTERFACE_IArchiveUpdateCallbackFile(;) + // INTERFACE_IArchiveUpdateCallbackArcProp(;) INTERFACE_IArchiveExtractCallbackMessage(;) INTERFACE_IArchiveGetRawProps(;) INTERFACE_IArchiveGetRootProps(;) @@ -115,10 +125,11 @@ class CArchiveUpdateCallback: CRecordVector _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 VolumesSizes; FString VolName; @@ -148,8 +159,22 @@ class CArchiveUpdateCallback: 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 old mode 100644 new mode 100755 index 31d73f940..e9a16444b --- a/CPP/7zip/UI/Common/UpdatePair.cpp +++ b/CPP/7zip/UI/Common/UpdatePair.cpp @@ -3,6 +3,7 @@ #include "StdAfx.h" #include +// #include #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 &arcItems = *(const CObjectVector *)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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Common/UpdateProduce.cpp b/CPP/7zip/UI/Common/UpdateProduce.cpp old mode 100644 new mode 100755 index fa4bd69c6..e921dc326 --- 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 old mode 100644 new mode 100755 index 595370fe4..24bb32ec0 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Common/WorkDir.h b/CPP/7zip/UI/Common/WorkDir.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Common/ZipRegistry.cpp b/CPP/7zip/UI/Common/ZipRegistry.cpp old mode 100644 new mode 100755 index ab4871fb3..a67a99b62 --- 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 old mode 100644 new mode 100755 index 3d2e4b98c..b7075e677 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Console/BenchCon.h b/CPP/7zip/UI/Console/BenchCon.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Console/Console.dsp b/CPP/7zip/UI/Console/Console.dsp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Console/Console.dsw b/CPP/7zip/UI/Console/Console.dsw old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Console/Console.mak b/CPP/7zip/UI/Console/Console.mak old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Console/Console.manifest b/CPP/7zip/UI/Console/Console.manifest old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Console/ConsoleClose.cpp b/CPP/7zip/UI/Console/ConsoleClose.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Console/ConsoleClose.h b/CPP/7zip/UI/Console/ConsoleClose.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp b/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp old mode 100644 new mode 100755 index 24c21e8d2..7f791b00b --- 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 old mode 100644 new mode 100755 index 5ac1d0b0e..7964813d6 --- 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 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Console/HashCon.h b/CPP/7zip/UI/Console/HashCon.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Console/List.cpp b/CPP/7zip/UI/Console/List.cpp old mode 100644 new mode 100755 index 9000e57a5..f764f07e4 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Console/Main.cpp b/CPP/7zip/UI/Console/Main.cpp old mode 100644 new mode 100755 index 0455ed5de..d01aa4d05 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Console/OpenCallbackConsole.cpp b/CPP/7zip/UI/Console/OpenCallbackConsole.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Console/OpenCallbackConsole.h b/CPP/7zip/UI/Console/OpenCallbackConsole.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Console/PercentPrinter.cpp b/CPP/7zip/UI/Console/PercentPrinter.cpp old mode 100644 new mode 100755 index 4341fd9fa..49d039329 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Console/StdAfx.cpp b/CPP/7zip/UI/Console/StdAfx.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Console/StdAfx.h b/CPP/7zip/UI/Console/StdAfx.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp b/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp old mode 100644 new mode 100755 index 0a25c2251..1a6b820c4 --- 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 old mode 100644 new mode 100755 index 700d511cc..b7ffef036 --- a/CPP/7zip/UI/Console/UpdateCallbackConsole.h +++ b/CPP/7zip/UI/Console/UpdateCallbackConsole.h @@ -35,7 +35,8 @@ class CCallbackConsoleBase 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 @@ class CCallbackConsoleBase 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Console/UserInputUtils.h b/CPP/7zip/UI/Console/UserInputUtils.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Console/makefile b/CPP/7zip/UI/Console/makefile old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Console/makefile.gcc b/CPP/7zip/UI/Console/makefile.gcc old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Console/resource.rc b/CPP/7zip/UI/Console/resource.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Explorer/7-zip.dll.manifest b/CPP/7zip/UI/Explorer/7-zip.dll.manifest old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Explorer/ContextMenu.cpp b/CPP/7zip/UI/Explorer/ContextMenu.cpp old mode 100644 new mode 100755 index 690702113..7dbb5049b --- 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 old mode 100644 new mode 100755 index 285044e73..5b56d63b9 --- a/CPP/7zip/UI/Explorer/ContextMenu.h +++ b/CPP/7zip/UI/Explorer/ContextMenu.h @@ -129,6 +129,7 @@ class CZipContextMenu: 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Explorer/DllExportsExplorer.cpp b/CPP/7zip/UI/Explorer/DllExportsExplorer.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Explorer/Explorer.def b/CPP/7zip/UI/Explorer/Explorer.def old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Explorer/Explorer.dsp b/CPP/7zip/UI/Explorer/Explorer.dsp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Explorer/Explorer.dsw b/CPP/7zip/UI/Explorer/Explorer.dsw old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Explorer/MenuLogo.bmp b/CPP/7zip/UI/Explorer/MenuLogo.bmp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Explorer/MyExplorerCommand.h b/CPP/7zip/UI/Explorer/MyExplorerCommand.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Explorer/MyMessages.cpp b/CPP/7zip/UI/Explorer/MyMessages.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Explorer/MyMessages.h b/CPP/7zip/UI/Explorer/MyMessages.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Explorer/RegistryContextMenu.cpp b/CPP/7zip/UI/Explorer/RegistryContextMenu.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Explorer/RegistryContextMenu.h b/CPP/7zip/UI/Explorer/RegistryContextMenu.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Explorer/StdAfx.cpp b/CPP/7zip/UI/Explorer/StdAfx.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Explorer/StdAfx.h b/CPP/7zip/UI/Explorer/StdAfx.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Explorer/makefile b/CPP/7zip/UI/Explorer/makefile old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Explorer/resource.h b/CPP/7zip/UI/Explorer/resource.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Explorer/resource.rc b/CPP/7zip/UI/Explorer/resource.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Explorer/resource2.rc b/CPP/7zip/UI/Explorer/resource2.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Far/ExtractEngine.cpp b/CPP/7zip/UI/Far/ExtractEngine.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Far/ExtractEngine.h b/CPP/7zip/UI/Far/ExtractEngine.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Far/Far.cpp b/CPP/7zip/UI/Far/Far.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Far/Far.def b/CPP/7zip/UI/Far/Far.def old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Far/Far.dsp b/CPP/7zip/UI/Far/Far.dsp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Far/Far.dsw b/CPP/7zip/UI/Far/Far.dsw old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Far/FarPlugin.h b/CPP/7zip/UI/Far/FarPlugin.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Far/FarUtils.cpp b/CPP/7zip/UI/Far/FarUtils.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Far/FarUtils.h b/CPP/7zip/UI/Far/FarUtils.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Far/Messages.h b/CPP/7zip/UI/Far/Messages.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Far/OverwriteDialogFar.cpp b/CPP/7zip/UI/Far/OverwriteDialogFar.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Far/OverwriteDialogFar.h b/CPP/7zip/UI/Far/OverwriteDialogFar.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Far/Plugin.cpp b/CPP/7zip/UI/Far/Plugin.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Far/Plugin.h b/CPP/7zip/UI/Far/Plugin.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Far/PluginCommon.cpp b/CPP/7zip/UI/Far/PluginCommon.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Far/PluginDelete.cpp b/CPP/7zip/UI/Far/PluginDelete.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Far/PluginRead.cpp b/CPP/7zip/UI/Far/PluginRead.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Far/PluginWrite.cpp b/CPP/7zip/UI/Far/PluginWrite.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Far/ProgressBox.cpp b/CPP/7zip/UI/Far/ProgressBox.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Far/ProgressBox.h b/CPP/7zip/UI/Far/ProgressBox.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Far/StdAfx.cpp b/CPP/7zip/UI/Far/StdAfx.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Far/StdAfx.h b/CPP/7zip/UI/Far/StdAfx.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Far/UpdateCallbackFar.cpp b/CPP/7zip/UI/Far/UpdateCallbackFar.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Far/UpdateCallbackFar.h b/CPP/7zip/UI/Far/UpdateCallbackFar.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Far/makefile b/CPP/7zip/UI/Far/makefile old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/Far/resource.rc b/CPP/7zip/UI/Far/resource.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/7zFM.exe.manifest b/CPP/7zip/UI/FileManager/7zFM.exe.manifest old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/7zipLogo.ico b/CPP/7zip/UI/FileManager/7zipLogo.ico old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/AboutDialog.cpp b/CPP/7zip/UI/FileManager/AboutDialog.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/AboutDialog.h b/CPP/7zip/UI/FileManager/AboutDialog.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/AboutDialog.rc b/CPP/7zip/UI/FileManager/AboutDialog.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/AboutDialogRes.h b/CPP/7zip/UI/FileManager/AboutDialogRes.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/Add.bmp b/CPP/7zip/UI/FileManager/Add.bmp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/Add2.bmp b/CPP/7zip/UI/FileManager/Add2.bmp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/AltStreamsFolder.cpp b/CPP/7zip/UI/FileManager/AltStreamsFolder.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/AltStreamsFolder.h b/CPP/7zip/UI/FileManager/AltStreamsFolder.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/App.cpp b/CPP/7zip/UI/FileManager/App.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/App.h b/CPP/7zip/UI/FileManager/App.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/AppState.h b/CPP/7zip/UI/FileManager/AppState.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/BrowseDialog.cpp b/CPP/7zip/UI/FileManager/BrowseDialog.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/BrowseDialog.h b/CPP/7zip/UI/FileManager/BrowseDialog.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/BrowseDialog.rc b/CPP/7zip/UI/FileManager/BrowseDialog.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/BrowseDialogRes.h b/CPP/7zip/UI/FileManager/BrowseDialogRes.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/ClassDefs.cpp b/CPP/7zip/UI/FileManager/ClassDefs.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/ComboDialog.cpp b/CPP/7zip/UI/FileManager/ComboDialog.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/ComboDialog.h b/CPP/7zip/UI/FileManager/ComboDialog.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/ComboDialog.rc b/CPP/7zip/UI/FileManager/ComboDialog.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/ComboDialogRes.h b/CPP/7zip/UI/FileManager/ComboDialogRes.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/Copy.bmp b/CPP/7zip/UI/FileManager/Copy.bmp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/Copy2.bmp b/CPP/7zip/UI/FileManager/Copy2.bmp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/CopyDialog.cpp b/CPP/7zip/UI/FileManager/CopyDialog.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/CopyDialog.h b/CPP/7zip/UI/FileManager/CopyDialog.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/CopyDialog.rc b/CPP/7zip/UI/FileManager/CopyDialog.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/CopyDialogRes.h b/CPP/7zip/UI/FileManager/CopyDialogRes.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/Delete.bmp b/CPP/7zip/UI/FileManager/Delete.bmp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/Delete2.bmp b/CPP/7zip/UI/FileManager/Delete2.bmp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/DialogSize.h b/CPP/7zip/UI/FileManager/DialogSize.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/EditDialog.cpp b/CPP/7zip/UI/FileManager/EditDialog.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/EditDialog.h b/CPP/7zip/UI/FileManager/EditDialog.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/EditDialog.rc b/CPP/7zip/UI/FileManager/EditDialog.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/EditDialogRes.h b/CPP/7zip/UI/FileManager/EditDialogRes.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/EditPage.cpp b/CPP/7zip/UI/FileManager/EditPage.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/EditPage.h b/CPP/7zip/UI/FileManager/EditPage.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/EditPage.rc b/CPP/7zip/UI/FileManager/EditPage.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/EditPage2.rc b/CPP/7zip/UI/FileManager/EditPage2.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/EditPageRes.h b/CPP/7zip/UI/FileManager/EditPageRes.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/EnumFormatEtc.cpp b/CPP/7zip/UI/FileManager/EnumFormatEtc.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/EnumFormatEtc.h b/CPP/7zip/UI/FileManager/EnumFormatEtc.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/Extract.bmp b/CPP/7zip/UI/FileManager/Extract.bmp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/Extract2.bmp b/CPP/7zip/UI/FileManager/Extract2.bmp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/ExtractCallback.cpp b/CPP/7zip/UI/FileManager/ExtractCallback.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/ExtractCallback.h b/CPP/7zip/UI/FileManager/ExtractCallback.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/FM.cpp b/CPP/7zip/UI/FileManager/FM.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/FM.dsp b/CPP/7zip/UI/FileManager/FM.dsp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/FM.dsw b/CPP/7zip/UI/FileManager/FM.dsw old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/FM.ico b/CPP/7zip/UI/FileManager/FM.ico old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/FM.mak b/CPP/7zip/UI/FileManager/FM.mak old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/FSDrives.cpp b/CPP/7zip/UI/FileManager/FSDrives.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/FSDrives.h b/CPP/7zip/UI/FileManager/FSDrives.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/FSFolder.cpp b/CPP/7zip/UI/FileManager/FSFolder.cpp old mode 100644 new mode 100755 index f3e04b3c5..72cb0ce0e --- 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 +#else +// mingw +#include +#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 old mode 100644 new mode 100755 index fac1ef97c..4f8c3449d --- 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 @@ class CFSFolder: #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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp b/CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/FileFolderPluginOpen.h b/CPP/7zip/UI/FileManager/FileFolderPluginOpen.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/FilePlugins.cpp b/CPP/7zip/UI/FileManager/FilePlugins.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/FilePlugins.h b/CPP/7zip/UI/FileManager/FilePlugins.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/FoldersPage.cpp b/CPP/7zip/UI/FileManager/FoldersPage.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/FoldersPage.h b/CPP/7zip/UI/FileManager/FoldersPage.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/FoldersPage.rc b/CPP/7zip/UI/FileManager/FoldersPage.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/FoldersPage2.rc b/CPP/7zip/UI/FileManager/FoldersPage2.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/FoldersPageRes.h b/CPP/7zip/UI/FileManager/FoldersPageRes.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/FormatUtils.cpp b/CPP/7zip/UI/FileManager/FormatUtils.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/FormatUtils.h b/CPP/7zip/UI/FileManager/FormatUtils.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/HelpUtils.cpp b/CPP/7zip/UI/FileManager/HelpUtils.cpp old mode 100644 new mode 100755 index 2db950145..5cb78fc11 --- 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 +#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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/IFolder.h b/CPP/7zip/UI/FileManager/IFolder.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/Info.bmp b/CPP/7zip/UI/FileManager/Info.bmp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/Info2.bmp b/CPP/7zip/UI/FileManager/Info2.bmp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/LangPage.cpp b/CPP/7zip/UI/FileManager/LangPage.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/LangPage.h b/CPP/7zip/UI/FileManager/LangPage.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/LangPage.rc b/CPP/7zip/UI/FileManager/LangPage.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/LangPageRes.h b/CPP/7zip/UI/FileManager/LangPageRes.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/LangUtils.cpp b/CPP/7zip/UI/FileManager/LangUtils.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/LangUtils.h b/CPP/7zip/UI/FileManager/LangUtils.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/LinkDialog.cpp b/CPP/7zip/UI/FileManager/LinkDialog.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/LinkDialog.h b/CPP/7zip/UI/FileManager/LinkDialog.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/LinkDialog.rc b/CPP/7zip/UI/FileManager/LinkDialog.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/LinkDialogRes.h b/CPP/7zip/UI/FileManager/LinkDialogRes.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/ListViewDialog.cpp b/CPP/7zip/UI/FileManager/ListViewDialog.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/ListViewDialog.h b/CPP/7zip/UI/FileManager/ListViewDialog.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/ListViewDialog.rc b/CPP/7zip/UI/FileManager/ListViewDialog.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/ListViewDialogRes.h b/CPP/7zip/UI/FileManager/ListViewDialogRes.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/MenuPage.cpp b/CPP/7zip/UI/FileManager/MenuPage.cpp old mode 100644 new mode 100755 index 05f24d712..32dabaec0 --- 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 old mode 100644 new mode 100755 index 3807d9dd3..02aee6d75 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/MenuPage2.rc b/CPP/7zip/UI/FileManager/MenuPage2.rc old mode 100644 new mode 100755 index af86226df..4d1ba2146 --- 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 old mode 100644 new mode 100755 index ae0bf66d2..e2cf79852 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/MessagesDialog.h b/CPP/7zip/UI/FileManager/MessagesDialog.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/MessagesDialog.rc b/CPP/7zip/UI/FileManager/MessagesDialog.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/MessagesDialogRes.h b/CPP/7zip/UI/FileManager/MessagesDialogRes.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/Move.bmp b/CPP/7zip/UI/FileManager/Move.bmp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/Move2.bmp b/CPP/7zip/UI/FileManager/Move2.bmp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/MyCom2.h b/CPP/7zip/UI/FileManager/MyCom2.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/MyLoadMenu.cpp b/CPP/7zip/UI/FileManager/MyLoadMenu.cpp old mode 100644 new mode 100755 index d87dfe386..3973bb27d --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/MyWindowsNew.h b/CPP/7zip/UI/FileManager/MyWindowsNew.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/NetFolder.cpp b/CPP/7zip/UI/FileManager/NetFolder.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/NetFolder.h b/CPP/7zip/UI/FileManager/NetFolder.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/OpenCallback.cpp b/CPP/7zip/UI/FileManager/OpenCallback.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/OpenCallback.h b/CPP/7zip/UI/FileManager/OpenCallback.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/OptionsDialog.cpp b/CPP/7zip/UI/FileManager/OptionsDialog.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/OverwriteDialog.cpp b/CPP/7zip/UI/FileManager/OverwriteDialog.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/OverwriteDialog.h b/CPP/7zip/UI/FileManager/OverwriteDialog.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/OverwriteDialog.rc b/CPP/7zip/UI/FileManager/OverwriteDialog.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/OverwriteDialogRes.h b/CPP/7zip/UI/FileManager/OverwriteDialogRes.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/Panel.cpp b/CPP/7zip/UI/FileManager/Panel.cpp old mode 100644 new mode 100755 index e8c0b9475..f7cdb5b9c --- 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 old mode 100644 new mode 100755 index d1e4d2440..4755678e9 --- 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 old mode 100644 new mode 100755 index 7e1937c9a..2ea3e3bdf --- 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 setZoneMode; + FolderOperations.QueryInterface(IID_IFolderSetZoneIdMode, &setZoneMode); + if (setZoneMode) + { + RINOK(setZoneMode->SetZoneIdMode(options->ZoneIdMode)); + } + } + if (options->testMode) { CMyComPtr archiveFolder; @@ -126,6 +137,14 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector &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 &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 old mode 100644 new mode 100755 index 1d483ca18..32948d850 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/PanelFolderChange.cpp b/CPP/7zip/UI/FileManager/PanelFolderChange.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/PanelItemOpen.cpp b/CPP/7zip/UI/FileManager/PanelItemOpen.cpp old mode 100644 new mode 100755 index ba54491db..17301b5ed --- 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 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 old mode 100644 new mode 100755 index 33e445888..3cccf27e6 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/PanelListNotify.cpp b/CPP/7zip/UI/FileManager/PanelListNotify.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/PanelMenu.cpp b/CPP/7zip/UI/FileManager/PanelMenu.cpp old mode 100644 new mode 100755 index 1a09a8f65..9e86951c0 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/PanelSelect.cpp b/CPP/7zip/UI/FileManager/PanelSelect.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/PanelSort.cpp b/CPP/7zip/UI/FileManager/PanelSort.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/PanelSplitFile.cpp b/CPP/7zip/UI/FileManager/PanelSplitFile.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/PasswordDialog.cpp b/CPP/7zip/UI/FileManager/PasswordDialog.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/PasswordDialog.h b/CPP/7zip/UI/FileManager/PasswordDialog.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/PasswordDialog.rc b/CPP/7zip/UI/FileManager/PasswordDialog.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/PasswordDialogRes.h b/CPP/7zip/UI/FileManager/PasswordDialogRes.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/PluginInterface.h b/CPP/7zip/UI/FileManager/PluginInterface.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/PluginLoader.h b/CPP/7zip/UI/FileManager/PluginLoader.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/ProgramLocation.cpp b/CPP/7zip/UI/FileManager/ProgramLocation.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/ProgramLocation.h b/CPP/7zip/UI/FileManager/ProgramLocation.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/ProgressDialog.cpp b/CPP/7zip/UI/FileManager/ProgressDialog.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/ProgressDialog.h b/CPP/7zip/UI/FileManager/ProgressDialog.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/ProgressDialog.rc b/CPP/7zip/UI/FileManager/ProgressDialog.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2.cpp b/CPP/7zip/UI/FileManager/ProgressDialog2.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2.h b/CPP/7zip/UI/FileManager/ProgressDialog2.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2.rc b/CPP/7zip/UI/FileManager/ProgressDialog2.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2Res.h b/CPP/7zip/UI/FileManager/ProgressDialog2Res.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2a.rc b/CPP/7zip/UI/FileManager/ProgressDialog2a.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/ProgressDialogRes.h b/CPP/7zip/UI/FileManager/ProgressDialogRes.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/PropertyName.cpp b/CPP/7zip/UI/FileManager/PropertyName.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/PropertyName.h b/CPP/7zip/UI/FileManager/PropertyName.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/PropertyName.rc b/CPP/7zip/UI/FileManager/PropertyName.rc old mode 100644 new mode 100755 index 5de5aeec4..e16c526ff --- 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 old mode 100644 new mode 100755 index 67f339028..e3d08db97 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/RegistryAssociations.h b/CPP/7zip/UI/FileManager/RegistryAssociations.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/RegistryPlugins.cpp b/CPP/7zip/UI/FileManager/RegistryPlugins.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/RegistryPlugins.h b/CPP/7zip/UI/FileManager/RegistryPlugins.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/RegistryUtils.cpp b/CPP/7zip/UI/FileManager/RegistryUtils.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/RegistryUtils.h b/CPP/7zip/UI/FileManager/RegistryUtils.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/RootFolder.cpp b/CPP/7zip/UI/FileManager/RootFolder.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/RootFolder.h b/CPP/7zip/UI/FileManager/RootFolder.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/SettingsPage.cpp b/CPP/7zip/UI/FileManager/SettingsPage.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/SettingsPage.h b/CPP/7zip/UI/FileManager/SettingsPage.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/SettingsPage.rc b/CPP/7zip/UI/FileManager/SettingsPage.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/SettingsPage2.rc b/CPP/7zip/UI/FileManager/SettingsPage2.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/SettingsPageRes.h b/CPP/7zip/UI/FileManager/SettingsPageRes.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/SplitDialog.cpp b/CPP/7zip/UI/FileManager/SplitDialog.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/SplitDialog.h b/CPP/7zip/UI/FileManager/SplitDialog.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/SplitDialog.rc b/CPP/7zip/UI/FileManager/SplitDialog.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/SplitDialogRes.h b/CPP/7zip/UI/FileManager/SplitDialogRes.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/SplitUtils.cpp b/CPP/7zip/UI/FileManager/SplitUtils.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/SplitUtils.h b/CPP/7zip/UI/FileManager/SplitUtils.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/StdAfx.cpp b/CPP/7zip/UI/FileManager/StdAfx.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/StdAfx.h b/CPP/7zip/UI/FileManager/StdAfx.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/StringUtils.cpp b/CPP/7zip/UI/FileManager/StringUtils.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/StringUtils.h b/CPP/7zip/UI/FileManager/StringUtils.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/SysIconUtils.cpp b/CPP/7zip/UI/FileManager/SysIconUtils.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/SysIconUtils.h b/CPP/7zip/UI/FileManager/SysIconUtils.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/SystemPage.cpp b/CPP/7zip/UI/FileManager/SystemPage.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/SystemPage.h b/CPP/7zip/UI/FileManager/SystemPage.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/SystemPage.rc b/CPP/7zip/UI/FileManager/SystemPage.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/SystemPageRes.h b/CPP/7zip/UI/FileManager/SystemPageRes.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/Test.bmp b/CPP/7zip/UI/FileManager/Test.bmp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/Test2.bmp b/CPP/7zip/UI/FileManager/Test2.bmp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/TextPairs.cpp b/CPP/7zip/UI/FileManager/TextPairs.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/TextPairs.h b/CPP/7zip/UI/FileManager/TextPairs.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/UpdateCallback100.cpp b/CPP/7zip/UI/FileManager/UpdateCallback100.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/UpdateCallback100.h b/CPP/7zip/UI/FileManager/UpdateCallback100.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/VerCtrl.cpp b/CPP/7zip/UI/FileManager/VerCtrl.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/ViewSettings.cpp b/CPP/7zip/UI/FileManager/ViewSettings.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/ViewSettings.h b/CPP/7zip/UI/FileManager/ViewSettings.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/makefile b/CPP/7zip/UI/FileManager/makefile old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/resource.h b/CPP/7zip/UI/FileManager/resource.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/resource.rc b/CPP/7zip/UI/FileManager/resource.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/resourceGui.h b/CPP/7zip/UI/FileManager/resourceGui.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/FileManager/resourceGui.rc b/CPP/7zip/UI/FileManager/resourceGui.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/GUI/7zG.exe.manifest b/CPP/7zip/UI/GUI/7zG.exe.manifest old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/GUI/BenchmarkDialog.cpp b/CPP/7zip/UI/GUI/BenchmarkDialog.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/GUI/BenchmarkDialog.h b/CPP/7zip/UI/GUI/BenchmarkDialog.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/GUI/BenchmarkDialog.rc b/CPP/7zip/UI/GUI/BenchmarkDialog.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/GUI/BenchmarkDialogRes.h b/CPP/7zip/UI/GUI/BenchmarkDialogRes.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/GUI/CompressDialog.cpp b/CPP/7zip/UI/GUI/CompressDialog.cpp old mode 100644 new mode 100755 index 16a358540..25b92194f --- 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 &userCodecs) { @@ -375,12 +379,13 @@ void CCompressDialog::SetMethods(const CObjectVector &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 ®) +{ + 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 old mode 100644 new mode 100755 index 171d1189d..d4590c9b2 --- 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 *ArcFormats; CUIntVector ArcIndices; // can not be empty, must contain Info.FormatIndex, if Info.FormatIndex >= 0 @@ -313,11 +365,103 @@ class CCompressDialog: public NWindows::NControl::CModalDialog 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 old mode 100644 new mode 100755 index 52c9546a4..d47a3eddf --- 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 old mode 100644 new mode 100755 index 341b75334..80b39be51 --- 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 000000000..05782270d --- /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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/GUI/ExtractDialog.cpp b/CPP/7zip/UI/GUI/ExtractDialog.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/GUI/ExtractDialog.h b/CPP/7zip/UI/GUI/ExtractDialog.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/GUI/ExtractDialog.rc b/CPP/7zip/UI/GUI/ExtractDialog.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/GUI/ExtractDialogRes.h b/CPP/7zip/UI/GUI/ExtractDialogRes.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/GUI/ExtractGUI.cpp b/CPP/7zip/UI/GUI/ExtractGUI.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/GUI/ExtractGUI.h b/CPP/7zip/UI/GUI/ExtractGUI.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/GUI/ExtractRes.h b/CPP/7zip/UI/GUI/ExtractRes.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/GUI/FM.ico b/CPP/7zip/UI/GUI/FM.ico old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/GUI/GUI.cpp b/CPP/7zip/UI/GUI/GUI.cpp old mode 100644 new mode 100755 index 32a48e743..c977516c2 --- 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 old mode 100644 new mode 100755 index 53a2c92f8..b55a115c5 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/GUI/HashGUI.cpp b/CPP/7zip/UI/GUI/HashGUI.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/GUI/HashGUI.h b/CPP/7zip/UI/GUI/HashGUI.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/GUI/StdAfx.cpp b/CPP/7zip/UI/GUI/StdAfx.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/GUI/StdAfx.h b/CPP/7zip/UI/GUI/StdAfx.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp b/CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/GUI/UpdateCallbackGUI.h b/CPP/7zip/UI/GUI/UpdateCallbackGUI.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/GUI/UpdateCallbackGUI2.cpp b/CPP/7zip/UI/GUI/UpdateCallbackGUI2.cpp old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/GUI/UpdateCallbackGUI2.h b/CPP/7zip/UI/GUI/UpdateCallbackGUI2.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/GUI/UpdateGUI.cpp b/CPP/7zip/UI/GUI/UpdateGUI.cpp old mode 100644 new mode 100755 index a3a1d889a..2d041437f --- 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 &properties, + NCompressDialog::CInfo &di) +{ + FOR_VECTOR (i, properties) + { + ParseProp(properties[i], di); + } +} + + + + + static void AddProp_UString(CObjectVector &properties, const char *name, const UString &value) { CProperty prop; @@ -81,10 +128,31 @@ static void AddProp_bool(CObjectVector &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 &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 &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 &properties, const char *name, static void SetOutProperties( CObjectVector &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 old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/GUI/makefile b/CPP/7zip/UI/GUI/makefile old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/GUI/resource.rc b/CPP/7zip/UI/GUI/resource.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/GUI/resource2.h b/CPP/7zip/UI/GUI/resource2.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/GUI/resource2.rc b/CPP/7zip/UI/GUI/resource2.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/GUI/resource3.h b/CPP/7zip/UI/GUI/resource3.h old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/GUI/resource3.rc b/CPP/7zip/UI/GUI/resource3.rc old mode 100644 new mode 100755 diff --git a/CPP/7zip/UI/makefile b/CPP/7zip/UI/makefile old mode 100644 new mode 100755 diff --git a/CPP/7zip/cmpl_clang.mak b/CPP/7zip/cmpl_clang.mak old mode 100644 new mode 100755 diff --git a/CPP/7zip/cmpl_clang_arm64.mak b/CPP/7zip/cmpl_clang_arm64.mak old mode 100644 new mode 100755 diff --git a/CPP/7zip/cmpl_clang_x64.mak b/CPP/7zip/cmpl_clang_x64.mak old mode 100644 new mode 100755 diff --git a/CPP/7zip/cmpl_clang_x86.mak b/CPP/7zip/cmpl_clang_x86.mak old mode 100644 new mode 100755 diff --git a/CPP/7zip/cmpl_gcc.mak b/CPP/7zip/cmpl_gcc.mak old mode 100644 new mode 100755 diff --git a/CPP/7zip/cmpl_gcc_arm64.mak b/CPP/7zip/cmpl_gcc_arm64.mak old mode 100644 new mode 100755 diff --git a/CPP/7zip/cmpl_gcc_x64.mak b/CPP/7zip/cmpl_gcc_x64.mak old mode 100644 new mode 100755 diff --git a/CPP/7zip/cmpl_gcc_x86.mak b/CPP/7zip/cmpl_gcc_x86.mak old mode 100644 new mode 100755 diff --git a/CPP/7zip/cmpl_mac_arm64.mak b/CPP/7zip/cmpl_mac_arm64.mak old mode 100644 new mode 100755 diff --git a/CPP/7zip/cmpl_mac_x64.mak b/CPP/7zip/cmpl_mac_x64.mak old mode 100644 new mode 100755 diff --git a/CPP/7zip/makefile b/CPP/7zip/makefile old mode 100644 new mode 100755 diff --git a/CPP/7zip/var_clang.mak b/CPP/7zip/var_clang.mak old mode 100644 new mode 100755 diff --git a/CPP/7zip/var_clang_arm64.mak b/CPP/7zip/var_clang_arm64.mak old mode 100644 new mode 100755 diff --git a/CPP/7zip/var_clang_x64.mak b/CPP/7zip/var_clang_x64.mak old mode 100644 new mode 100755 diff --git a/CPP/7zip/var_clang_x86.mak b/CPP/7zip/var_clang_x86.mak old mode 100644 new mode 100755 diff --git a/CPP/7zip/var_gcc.mak b/CPP/7zip/var_gcc.mak old mode 100644 new mode 100755 diff --git a/CPP/7zip/var_gcc_arm64.mak b/CPP/7zip/var_gcc_arm64.mak old mode 100644 new mode 100755 diff --git a/CPP/7zip/var_gcc_x64.mak b/CPP/7zip/var_gcc_x64.mak old mode 100644 new mode 100755 diff --git a/CPP/7zip/var_gcc_x86.mak b/CPP/7zip/var_gcc_x86.mak old mode 100644 new mode 100755 diff --git a/CPP/7zip/var_mac_arm64.mak b/CPP/7zip/var_mac_arm64.mak old mode 100644 new mode 100755 diff --git a/CPP/7zip/var_mac_x64.mak b/CPP/7zip/var_mac_x64.mak old mode 100644 new mode 100755 diff --git a/CPP/7zip/warn_clang.mak b/CPP/7zip/warn_clang.mak old mode 100644 new mode 100755 diff --git a/CPP/7zip/warn_clang_mac.mak b/CPP/7zip/warn_clang_mac.mak old mode 100644 new mode 100755 diff --git a/CPP/7zip/warn_gcc.mak b/CPP/7zip/warn_gcc.mak old mode 100644 new mode 100755 diff --git a/CPP/Build.mak b/CPP/Build.mak old mode 100644 new mode 100755 diff --git a/CPP/Common/AutoPtr.h b/CPP/Common/AutoPtr.h old mode 100644 new mode 100755 diff --git a/CPP/Common/CRC.cpp b/CPP/Common/CRC.cpp old mode 100644 new mode 100755 diff --git a/CPP/Common/C_FileIO.cpp b/CPP/Common/C_FileIO.cpp old mode 100644 new mode 100755 diff --git a/CPP/Common/C_FileIO.h b/CPP/Common/C_FileIO.h old mode 100644 new mode 100755 diff --git a/CPP/Common/CksumReg.cpp b/CPP/Common/CksumReg.cpp old mode 100644 new mode 100755 diff --git a/CPP/Common/ComTry.h b/CPP/Common/ComTry.h old mode 100644 new mode 100755 diff --git a/CPP/Common/CommandLineParser.cpp b/CPP/Common/CommandLineParser.cpp old mode 100644 new mode 100755 diff --git a/CPP/Common/CommandLineParser.h b/CPP/Common/CommandLineParser.h old mode 100644 new mode 100755 diff --git a/CPP/Common/Common.h b/CPP/Common/Common.h old mode 100644 new mode 100755 index 8dac613c0..72db7a8bf --- 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 old mode 100644 new mode 100755 diff --git a/CPP/Common/Defs.h b/CPP/Common/Defs.h old mode 100644 new mode 100755 diff --git a/CPP/Common/DynLimBuf.cpp b/CPP/Common/DynLimBuf.cpp old mode 100644 new mode 100755 diff --git a/CPP/Common/DynLimBuf.h b/CPP/Common/DynLimBuf.h old mode 100644 new mode 100755 diff --git a/CPP/Common/DynamicBuffer.h b/CPP/Common/DynamicBuffer.h old mode 100644 new mode 100755 diff --git a/CPP/Common/IntToString.cpp b/CPP/Common/IntToString.cpp old mode 100644 new mode 100755 diff --git a/CPP/Common/IntToString.h b/CPP/Common/IntToString.h old mode 100644 new mode 100755 diff --git a/CPP/Common/Lang.cpp b/CPP/Common/Lang.cpp old mode 100644 new mode 100755 diff --git a/CPP/Common/Lang.h b/CPP/Common/Lang.h old mode 100644 new mode 100755 diff --git a/CPP/Common/ListFileUtils.cpp b/CPP/Common/ListFileUtils.cpp old mode 100644 new mode 100755 diff --git a/CPP/Common/ListFileUtils.h b/CPP/Common/ListFileUtils.h old mode 100644 new mode 100755 diff --git a/CPP/Common/LzFindPrepare.cpp b/CPP/Common/LzFindPrepare.cpp old mode 100644 new mode 100755 diff --git a/CPP/Common/MyBuffer.h b/CPP/Common/MyBuffer.h old mode 100644 new mode 100755 diff --git a/CPP/Common/MyBuffer2.h b/CPP/Common/MyBuffer2.h old mode 100644 new mode 100755 diff --git a/CPP/Common/MyCom.h b/CPP/Common/MyCom.h old mode 100644 new mode 100755 index ce2f0dd15..ff5427806 --- a/CPP/Common/MyCom.h +++ b/CPP/Common/MyCom.h @@ -67,6 +67,7 @@ class CMyComPtr template 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 old mode 100644 new mode 100755 diff --git a/CPP/Common/MyGuidDef.h b/CPP/Common/MyGuidDef.h old mode 100644 new mode 100755 diff --git a/CPP/Common/MyInitGuid.h b/CPP/Common/MyInitGuid.h old mode 100644 new mode 100755 diff --git a/CPP/Common/MyLinux.h b/CPP/Common/MyLinux.h old mode 100644 new mode 100755 index 1a9189935..98b453c11 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/Common/MyMap.h b/CPP/Common/MyMap.h old mode 100644 new mode 100755 diff --git a/CPP/Common/MyString.cpp b/CPP/Common/MyString.cpp old mode 100644 new mode 100755 index db202f4c6..bf1638ebe --- 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 old mode 100644 new mode 100755 index aa3c301a0..c777c8c3e --- a/CPP/Common/MyString.h +++ b/CPP/Common/MyString.h @@ -378,6 +378,7 @@ class AString 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 @@ class AString 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 old mode 100644 new mode 100755 diff --git a/CPP/Common/MyUnknown.h b/CPP/Common/MyUnknown.h old mode 100644 new mode 100755 diff --git a/CPP/Common/MyVector.cpp b/CPP/Common/MyVector.cpp old mode 100644 new mode 100755 diff --git a/CPP/Common/MyVector.h b/CPP/Common/MyVector.h old mode 100644 new mode 100755 index c8512342f..3417a176b --- a/CPP/Common/MyVector.h +++ b/CPP/Common/MyVector.h @@ -5,6 +5,8 @@ #include +const unsigned k_VectorSizeMax = ((unsigned)1 << 31) - 1; + template 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 @@ class CRecordVector { 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 @@ class CRecordVector _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 @@ class CRecordVector 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 @@ class CRecordVector { if (&v == this) return *this; - unsigned size = v.Size(); + const unsigned size = v.Size(); if (size > _capacity) { delete []_items; @@ -196,24 +196,45 @@ class CRecordVector 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 @@ class CRecordVector _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 @@ class CRecordVector { 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 @@ class CRecordVector { 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 @@ class CRecordVector 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 @@ class CRecordVector 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 @@ class CObjectVector 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 @@ class CObjectVector 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 @@ class CObjectVector 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 @@ class CObjectVector 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 @@ class CObjectVector 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 @@ class CObjectVector 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 @@ class CObjectVector 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 old mode 100644 new mode 100755 diff --git a/CPP/Common/MyWindows.h b/CPP/Common/MyWindows.h old mode 100644 new mode 100755 index 0664a5e00..15db52434 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/Common/MyXml.h b/CPP/Common/MyXml.h old mode 100644 new mode 100755 diff --git a/CPP/Common/NewHandler.cpp b/CPP/Common/NewHandler.cpp old mode 100644 new mode 100755 index 7e5b1d451..65ef41d4f --- 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 @@ class CC } ~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 old mode 100644 new mode 100755 diff --git a/CPP/Common/Random.cpp b/CPP/Common/Random.cpp old mode 100644 new mode 100755 diff --git a/CPP/Common/Random.h b/CPP/Common/Random.h old mode 100644 new mode 100755 diff --git a/CPP/Common/Sha1Prepare.cpp b/CPP/Common/Sha1Prepare.cpp old mode 100644 new mode 100755 diff --git a/CPP/Common/Sha1Reg.cpp b/CPP/Common/Sha1Reg.cpp old mode 100644 new mode 100755 diff --git a/CPP/Common/Sha256Prepare.cpp b/CPP/Common/Sha256Prepare.cpp old mode 100644 new mode 100755 diff --git a/CPP/Common/Sha256Reg.cpp b/CPP/Common/Sha256Reg.cpp old mode 100644 new mode 100755 diff --git a/CPP/Common/StdAfx.h b/CPP/Common/StdAfx.h old mode 100644 new mode 100755 diff --git a/CPP/Common/StdInStream.cpp b/CPP/Common/StdInStream.cpp old mode 100644 new mode 100755 diff --git a/CPP/Common/StdInStream.h b/CPP/Common/StdInStream.h old mode 100644 new mode 100755 diff --git a/CPP/Common/StdOutStream.cpp b/CPP/Common/StdOutStream.cpp old mode 100644 new mode 100755 diff --git a/CPP/Common/StdOutStream.h b/CPP/Common/StdOutStream.h old mode 100644 new mode 100755 diff --git a/CPP/Common/StringConvert.cpp b/CPP/Common/StringConvert.cpp old mode 100644 new mode 100755 diff --git a/CPP/Common/StringConvert.h b/CPP/Common/StringConvert.h old mode 100644 new mode 100755 diff --git a/CPP/Common/StringToInt.cpp b/CPP/Common/StringToInt.cpp old mode 100644 new mode 100755 index 839867a45..bc4926e5d --- 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 old mode 100644 new mode 100755 index 5c5d7d7fe..4057e494e --- 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 old mode 100644 new mode 100755 diff --git a/CPP/Common/TextConfig.h b/CPP/Common/TextConfig.h old mode 100644 new mode 100755 diff --git a/CPP/Common/UTFConvert.cpp b/CPP/Common/UTFConvert.cpp old mode 100644 new mode 100755 diff --git a/CPP/Common/UTFConvert.h b/CPP/Common/UTFConvert.h old mode 100644 new mode 100755 diff --git a/CPP/Common/Wildcard.cpp b/CPP/Common/Wildcard.cpp old mode 100644 new mode 100755 diff --git a/CPP/Common/Wildcard.h b/CPP/Common/Wildcard.h old mode 100644 new mode 100755 diff --git a/CPP/Common/XzCrc64Init.cpp b/CPP/Common/XzCrc64Init.cpp old mode 100644 new mode 100755 diff --git a/CPP/Common/XzCrc64Reg.cpp b/CPP/Common/XzCrc64Reg.cpp old mode 100644 new mode 100755 diff --git a/CPP/Windows/COM.cpp b/CPP/Windows/COM.cpp old mode 100644 new mode 100755 diff --git a/CPP/Windows/COM.h b/CPP/Windows/COM.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/Clipboard.cpp b/CPP/Windows/Clipboard.cpp old mode 100644 new mode 100755 diff --git a/CPP/Windows/Clipboard.h b/CPP/Windows/Clipboard.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/CommonDialog.cpp b/CPP/Windows/CommonDialog.cpp old mode 100644 new mode 100755 diff --git a/CPP/Windows/CommonDialog.h b/CPP/Windows/CommonDialog.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/Console.cpp b/CPP/Windows/Console.cpp old mode 100644 new mode 100755 diff --git a/CPP/Windows/Console.h b/CPP/Windows/Console.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/Control/ComboBox.cpp b/CPP/Windows/Control/ComboBox.cpp old mode 100644 new mode 100755 diff --git a/CPP/Windows/Control/ComboBox.h b/CPP/Windows/Control/ComboBox.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/Control/CommandBar.h b/CPP/Windows/Control/CommandBar.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/Control/Dialog.cpp b/CPP/Windows/Control/Dialog.cpp old mode 100644 new mode 100755 diff --git a/CPP/Windows/Control/Dialog.h b/CPP/Windows/Control/Dialog.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/Control/Edit.h b/CPP/Windows/Control/Edit.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/Control/ImageList.cpp b/CPP/Windows/Control/ImageList.cpp old mode 100644 new mode 100755 diff --git a/CPP/Windows/Control/ImageList.h b/CPP/Windows/Control/ImageList.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/Control/ListView.cpp b/CPP/Windows/Control/ListView.cpp old mode 100644 new mode 100755 diff --git a/CPP/Windows/Control/ListView.h b/CPP/Windows/Control/ListView.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/Control/ProgressBar.h b/CPP/Windows/Control/ProgressBar.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/Control/PropertyPage.cpp b/CPP/Windows/Control/PropertyPage.cpp old mode 100644 new mode 100755 diff --git a/CPP/Windows/Control/PropertyPage.h b/CPP/Windows/Control/PropertyPage.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/Control/ReBar.h b/CPP/Windows/Control/ReBar.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/Control/Static.h b/CPP/Windows/Control/Static.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/Control/StatusBar.h b/CPP/Windows/Control/StatusBar.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/Control/StdAfx.h b/CPP/Windows/Control/StdAfx.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/Control/ToolBar.h b/CPP/Windows/Control/ToolBar.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/Control/Trackbar.h b/CPP/Windows/Control/Trackbar.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/Control/Window2.cpp b/CPP/Windows/Control/Window2.cpp old mode 100644 new mode 100755 diff --git a/CPP/Windows/Control/Window2.h b/CPP/Windows/Control/Window2.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/DLL.cpp b/CPP/Windows/DLL.cpp old mode 100644 new mode 100755 diff --git a/CPP/Windows/DLL.h b/CPP/Windows/DLL.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/Defs.h b/CPP/Windows/Defs.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/ErrorMsg.cpp b/CPP/Windows/ErrorMsg.cpp old mode 100644 new mode 100755 diff --git a/CPP/Windows/ErrorMsg.h b/CPP/Windows/ErrorMsg.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/FileDir.cpp b/CPP/Windows/FileDir.cpp old mode 100644 new mode 100755 index 8a33fc8ee..cce263858 --- 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 old mode 100644 new mode 100755 index 6d6ddeafe..08281aaa9 --- 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 old mode 100644 new mode 100755 index 591f8df0d..c6557599a --- a/CPP/Windows/FileFind.cpp +++ b/CPP/Windows/FileFind.cpp @@ -7,6 +7,8 @@ #ifndef _WIN32 #include /* Definition of AT_* constants */ #include "TimeUtils.h" +// for major +// #include #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 old mode 100644 new mode 100755 index 8f28ee330..fcfe02c7e --- a/CPP/Windows/FileFind.h +++ b/CPP/Windows/FileFind.h @@ -9,10 +9,14 @@ #include #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 @@ class CFileInfoBase 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 @@ class CFileInfoBase 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 old mode 100644 new mode 100755 index 2974b1b7a..e51b0eb31 --- a/CPP/Windows/FileIO.cpp +++ b/CPP/Windows/FileIO.cpp @@ -8,6 +8,14 @@ // #include +/* +#ifndef _WIN32 +// for ioctl BLKGETSIZE64 +#include +#include +#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 + 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 old mode 100644 new mode 100755 index 22998ebeb..80509653e --- 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 @@ class CFileBase MY_UNCOPYABLE 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 @@ class CInFile: public CFileBase #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 @@ class COutFile: public CFileBase 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 @@ class CFileBase 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 @@ class COutFile: public CFileBase { 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 old mode 100644 new mode 100755 diff --git a/CPP/Windows/FileMapping.cpp b/CPP/Windows/FileMapping.cpp old mode 100644 new mode 100755 diff --git a/CPP/Windows/FileMapping.h b/CPP/Windows/FileMapping.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/FileName.cpp b/CPP/Windows/FileName.cpp old mode 100644 new mode 100755 diff --git a/CPP/Windows/FileName.h b/CPP/Windows/FileName.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/FileSystem.cpp b/CPP/Windows/FileSystem.cpp old mode 100644 new mode 100755 diff --git a/CPP/Windows/FileSystem.h b/CPP/Windows/FileSystem.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/Handle.h b/CPP/Windows/Handle.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/MemoryGlobal.cpp b/CPP/Windows/MemoryGlobal.cpp old mode 100644 new mode 100755 diff --git a/CPP/Windows/MemoryGlobal.h b/CPP/Windows/MemoryGlobal.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/MemoryLock.cpp b/CPP/Windows/MemoryLock.cpp old mode 100644 new mode 100755 diff --git a/CPP/Windows/MemoryLock.h b/CPP/Windows/MemoryLock.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/Menu.cpp b/CPP/Windows/Menu.cpp old mode 100644 new mode 100755 diff --git a/CPP/Windows/Menu.h b/CPP/Windows/Menu.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/NationalTime.cpp b/CPP/Windows/NationalTime.cpp old mode 100644 new mode 100755 diff --git a/CPP/Windows/NationalTime.h b/CPP/Windows/NationalTime.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/Net.cpp b/CPP/Windows/Net.cpp old mode 100644 new mode 100755 diff --git a/CPP/Windows/Net.h b/CPP/Windows/Net.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/NtCheck.h b/CPP/Windows/NtCheck.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/ProcessMessages.cpp b/CPP/Windows/ProcessMessages.cpp old mode 100644 new mode 100755 diff --git a/CPP/Windows/ProcessMessages.h b/CPP/Windows/ProcessMessages.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/ProcessUtils.cpp b/CPP/Windows/ProcessUtils.cpp old mode 100644 new mode 100755 diff --git a/CPP/Windows/ProcessUtils.h b/CPP/Windows/ProcessUtils.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/PropVariant.cpp b/CPP/Windows/PropVariant.cpp old mode 100644 new mode 100755 index 6e43c7bcb..2b1795004 --- 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 old mode 100644 new mode 100755 index 108bf6b9d..171402f74 --- 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 @@ class CPropVariant : public tagPROPVARIANT // 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 @@ class CPropVariant : public tagPROPVARIANT 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 old mode 100644 new mode 100755 index b58d37e67..3c9bbd170 --- 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 old mode 100644 new mode 100755 index 390e0b89c..606778406 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/Windows/PropVariantUtils.h b/CPP/Windows/PropVariantUtils.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/Registry.cpp b/CPP/Windows/Registry.cpp old mode 100644 new mode 100755 diff --git a/CPP/Windows/Registry.h b/CPP/Windows/Registry.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/ResourceString.cpp b/CPP/Windows/ResourceString.cpp old mode 100644 new mode 100755 diff --git a/CPP/Windows/ResourceString.h b/CPP/Windows/ResourceString.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/SecurityUtils.cpp b/CPP/Windows/SecurityUtils.cpp old mode 100644 new mode 100755 index 640c90dc2..8a7f45cd1 --- 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 old mode 100644 new mode 100755 diff --git a/CPP/Windows/Shell.cpp b/CPP/Windows/Shell.cpp old mode 100644 new mode 100755 diff --git a/CPP/Windows/Shell.h b/CPP/Windows/Shell.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/StdAfx.h b/CPP/Windows/StdAfx.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/Synchronization.cpp b/CPP/Windows/Synchronization.cpp old mode 100644 new mode 100755 diff --git a/CPP/Windows/Synchronization.h b/CPP/Windows/Synchronization.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/System.cpp b/CPP/Windows/System.cpp old mode 100644 new mode 100755 diff --git a/CPP/Windows/System.h b/CPP/Windows/System.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/SystemInfo.cpp b/CPP/Windows/SystemInfo.cpp old mode 100644 new mode 100755 diff --git a/CPP/Windows/SystemInfo.h b/CPP/Windows/SystemInfo.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/Thread.h b/CPP/Windows/Thread.h old mode 100644 new mode 100755 diff --git a/CPP/Windows/TimeUtils.cpp b/CPP/Windows/TimeUtils.cpp old mode 100644 new mode 100755 index 1f1335f9a..77d2c5102 --- 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 old mode 100644 new mode 100755 index d1d8c150b..60ee739f2 --- 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 + + #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 old mode 100644 new mode 100755 diff --git a/CPP/Windows/Window.h b/CPP/Windows/Window.h old mode 100644 new mode 100755 diff --git a/DOC/7zC.txt b/DOC/7zC.txt old mode 100644 new mode 100755 diff --git a/DOC/7zFormat.txt b/DOC/7zFormat.txt old mode 100644 new mode 100755 diff --git a/DOC/7zip.hhp b/DOC/7zip.hhp old mode 100644 new mode 100755 diff --git a/DOC/7zip.wxs b/DOC/7zip.wxs old mode 100644 new mode 100755 index fdc63cea6..c7a61b441 --- a/DOC/7zip.wxs +++ b/DOC/7zip.wxs @@ -1,7 +1,7 @@ - - + + diff --git a/DOC/License.txt b/DOC/License.txt old mode 100644 new mode 100755 diff --git a/DOC/Methods.txt b/DOC/Methods.txt old mode 100644 new mode 100755 diff --git a/DOC/copying.txt b/DOC/copying.txt old mode 100644 new mode 100755 diff --git a/DOC/lzma.txt b/DOC/lzma.txt old mode 100644 new mode 100755 diff --git a/DOC/readme.txt b/DOC/readme.txt old mode 100644 new mode 100755 diff --git a/DOC/src-history.txt b/DOC/src-history.txt old mode 100644 new mode 100755 index 0b54fe347..f546c4e25 --- 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 old mode 100644 new mode 100755